From 472f0cb7d9ad7c8590d8d3269413f5eb6e82b519 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 25 Jul 2025 16:26:36 +0600 Subject: [PATCH 01/32] Non-working MKE/Panasonic interface --- src/cdrom/CMakeLists.txt | 1 + src/cdrom/cdrom.c | 2 + src/cdrom/cdrom_mke.c | 567 +++++++++++++++++++++++++++ src/config.c | 3 +- src/disk/hdd.c | 17 + src/include/86box/cdrom.h | 3 +- src/include/86box/cdrom_mke.h | 6 + src/qt/qt_harddrive_common.cpp | 13 +- src/qt/qt_machinestatus.cpp | 2 +- src/qt/qt_mediamenu.cpp | 7 +- src/qt/qt_settings_bus_tracking.cpp | 18 + src/qt/qt_settings_bus_tracking.hpp | 2 + src/qt/qt_settingsfloppycdrom.cpp | 14 +- src/qt/qt_settingsotherremovable.cpp | 2 + 14 files changed, 644 insertions(+), 13 deletions(-) create mode 100644 src/cdrom/cdrom_mke.c create mode 100644 src/include/86box/cdrom_mke.h diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 621b069b0..7e18a72a0 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(cdrom OBJECT cdrom.c cdrom_image.c cdrom_image_viso.c + cdrom_mke.c ) target_link_libraries(86Box PkgConfig::SNDFILE) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index a163c9390..d051ef7ed 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -32,6 +32,7 @@ #ifdef USE_CDROM_MITSUMI #include <86box/cdrom_mitsumi.h> #endif +#include <86box/cdrom_mke.h> #include <86box/log.h> #include <86box/plat.h> #include <86box/plat_cdrom_ioctl.h> @@ -123,6 +124,7 @@ static const struct { #ifdef USE_CDROM_MITSUMI { &mitsumi_cdrom_device }, #endif + { &mke_cdrom_device }, { NULL } // clang-format on }; diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c new file mode 100644 index 000000000..f303fb607 --- /dev/null +++ b/src/cdrom/cdrom_mke.c @@ -0,0 +1,567 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/dma.h> +#include <86box/cdrom.h> +#include <86box/cdrom_interface.h> +#include <86box/cdrom_mke.h> +#include <86box/plat.h> +#include <86box/sound.h> +#include <86box/fifo8.h> + +/* +https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h +CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix. +*/ +#define CDROM_STATUS_DOOR 0x80 +#define CDROM_STATUS_DISC_IN 0x40 +#define CDROM_STATUS_SPIN_UP 0x20 +#define CDROM_STATUS_ERROR 0x10 +#define CDROM_STATUS_DOUBLE_SPEED 0x02 +#define CDROM_STATUS_READY 0x01 + + +//Status returned from device +#define STAT_READY 0x01 +#define STAT_PLAY 0x08 +#define STAT_ERROR 0x10 +#define STAT_DISK 0x40 +#define STAT_TRAY 0x80 //Seems Correct + + +#define CMD1_PAUSERESUME 0x0D +#define CMD1_RESET 0x0a +#define CMD1_LOCK_CTL 0x0c +#define CMD1_TRAY_CTL 0x07 +#define CMD1_MULTISESS 0x8d +#define CMD1_SUBCHANINF 0x11 +#define CMD1_ABORT 0x08 +//#define CMD1_PATH_CHECK 0x??? +#define CMD1_SEEK 0x01 +#define CMD1_READ 0x10 +#define CMD1_SPINUP 0x02 +#define CMD1_SPINDOWN 0x06 +#define CMD1_READ_UPC 0x88 +//#define CMD1_PLAY 0x??? +#define CMD1_PLAY_MSF 0x0e +#define CMD1_PLAY_TI 0x0f +#define CMD1_STATUS 0x05 +#define CMD1_READ_ERR 0x82 +#define CMD1_READ_VER 0x83 +#define CMD1_SETMODE 0x09 +#define CMD1_GETMODE 0x84 +#define CMD1_CAPACITY 0x85 +#define CMD1_READSUBQ 0x87 +#define CMD1_DISKINFO 0x8b +#define CMD1_READTOC 0x8c +#define CMD1_PAU_RES 0x0d +#define CMD1_PACKET 0x8e +#define CMD1_SESSINFO 0x8d + +typedef struct mke_t { + bool tray_open; + + uint8_t enable_register; + + uint8_t command_buffer[7]; + uint8_t command_buffer_pending; + + uint8_t data_select; + + uint8_t media_selected;//temporary hack + + Fifo8 data_fifo, info_fifo; + Fifo8 errors_fifo; + + cdrom_t* cdrom_dev; + + uint32_t sector_type, sector_flags; + + uint32_t unit_attention; + + uint8_t cdbuffer[624240]; +} mke_t; +mke_t mke; + +#define mke_log(x, ...) + +#define CHECK_READY() { if (mke.cdrom_dev->image_path[0] == 0) { fifo8_push(&mke.errors_fifo, 0x03); return; } } + +static uint8_t temp_buf[65536]; + +void mke_get_subq(cdrom_t *dev,uint8_t *b) { + //dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + //cdrom_get_current_subchannel(dev, &subc); + //cdrom_get_current_subcodeq(dev, b); + cdrom_get_current_subcodeq(dev, temp_buf); + b[0] = 0x80; //? + b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); + b[2] = temp_buf[1]; + b[3] = temp_buf[2]; + b[4] = temp_buf[6]; + b[5] = temp_buf[7]; + b[6] = temp_buf[8]; + b[7] = temp_buf[3]; + b[8] = temp_buf[4]; + b[9] = temp_buf[5]; + b[10]=0; //?? +} + +uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { + track_info_t ti; + int first_track; + int last_track; + //dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + first_track = temp_buf[2]; + last_track = temp_buf[3]; + if(track > last_track) return 0; //should we allow +1 here? + dev->ops->get_track_info(dev, track, 0, &ti); + b[0]=0x0; + b[1]=ti.attr; + b[2]=ti.number; + b[3]=0; + b[4]=ti.m; + b[5]=ti.s; + b[6]=ti.f; + b[7]=0; + return 1; + +} +uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { + track_info_t ti; + int first_track; + int last_track; + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + first_track = temp_buf[2]; + last_track = temp_buf[3]; + dev->ops->get_track_info(dev, last_track+1, 0, &ti); + b[0]=0x0; + b[1]=first_track; + b[2]=last_track; + b[3]=ti.m; + b[4]=ti.s; + b[5]=ti.f; + return 1; + +} + +uint8_t mke_disc_capacity(cdrom_t *dev, unsigned char *b) { + track_info_t ti; + int first_track; + int last_track; + //dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + first_track = temp_buf[2]; + last_track = temp_buf[3]; + dev->ops->get_track_info(dev, last_track+1, 0, &ti); + b[0]=ti.m; + b[1]=ti.s; + b[2]=ti.f-1; //TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM + b[3]=0x08; + b[4]=0x00; + return 1; + +} + +uint8_t mke_cdrom_status(cdrom_t *dev, mke_t* mke) { + uint8_t status = 0; + status |= 2;//this bit seems to always be set? + //bit 4 never set? + if(dev->cd_status == CD_STATUS_PLAYING) status |= STAT_PLAY; + if(dev->cd_status == CD_STATUS_PAUSED) status |= STAT_PLAY; + if(fifo8_num_used(&mke->errors_fifo)) status |= 0x10; + status |= 0x20;//always set? + status |= STAT_TRAY; + if(dev->image_path[0] != 0) { + status |= STAT_DISK; + status |= STAT_READY; + } + + return status; +} + +void MKE_COMMAND(uint8_t value) { + uint16_t i,len; + uint8_t x[12];//this is wasteful handling of buffers for compatibility, but will optimize later. + subchannel_t subc; + int old_cd_status; + + if(mke.command_buffer_pending) { + mke.command_buffer[6-mke.command_buffer_pending+1]=value; + mke.command_buffer_pending--; + } + + if(mke.command_buffer[0] == CMD1_ABORT) { + mke_log("CMD_ABORT\n"); + //fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke.info_fifo); + mke.command_buffer[0]=0; + 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)); + } + + if (!mke.command_buffer_pending && mke.command_buffer[0]) { + switch (mke.command_buffer[0]) { + case 06: { + fifo8_reset(&mke.info_fifo); + cdrom_stop(mke.cdrom_dev); + cdrom_eject(mke.cdrom_dev->id); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + } + case 07: { + fifo8_reset(&mke.info_fifo); + cdrom_reload(mke.cdrom_dev->id); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + } + case CMD1_READ: { + //cdrom_readsector_raw(mke.cdrom_dev, ) + uint32_t count = mke.command_buffer[6]; + uint8_t* buf = mke.cdbuffer; + int len = 0; + int res = 0; + int error = 0; + uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]); + CHECK_READY(); + while (count) { + if ((res = cdrom_readsector_raw(mke.cdrom_dev, mke.cdbuffer, lba, 0, mke.sector_type, mke.sector_flags, &len, 0)) > 0) { + fifo8_push_all(&mke.data_fifo, buf, mke.cdrom_dev->sector_size); + lba++; + buf += mke.cdrom_dev->sector_size; + } else { + fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); + break; + } + count--; + } + if (count != 0) { + fifo8_reset(&mke.data_fifo); + } + break; + } + case CMD1_READSUBQ: + CHECK_READY(); + mke_get_subq(mke.cdrom_dev, (uint8_t *)&x); + fifo8_reset(&mke.info_fifo); + //fifo8_push_all(&cdrom.info_fifo, x, 11); + fifo8_push_all(&mke.info_fifo, x, 11); + /* + for(i=0;i<11;i++) { + cdrom_fifo_write(&cdrom.info_fifo,x[i]); + } + */ + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_SETMODE: //Returns 1 + fifo8_reset(&mke.info_fifo); + mke_log("CMD: SET MODE:"); + for(i=0;i<6;i++) { + mke_log("%02x ",mke.command_buffer[i+1]); + } + mke_log("\n"); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_GETMODE://6 + mke_log("GET MODE\n"); + uint8_t mode[5] = {[1] = 0x08}; + fifo8_push_all(&mke.info_fifo, mode, 5); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_PAUSERESUME: + CHECK_READY(); + cdrom_audio_pause_resume(mke.cdrom_dev, mke.command_buffer[1] >> 7); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_CAPACITY://6 + mke_log("DISK CAPACITY\n"); + CHECK_READY(); + mke_disc_capacity(mke.cdrom_dev, (uint8_t *)&x); + //fifo8_push_all(&cdrom.info_fifo, x, 5); + fifo8_push_all(&mke.info_fifo, x, 5); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_DISKINFO: //7 + mke_log("DISK INFO\n"); + CHECK_READY(); + mke_disc_info(mke.cdrom_dev, (uint8_t *)&x); + fifo8_push_all(&mke.info_fifo, x, 6); + /* + for(i=0;i<6;i++) { + mke_log("%02x ",x[i]); + cdrom_fifo_write(&cdrom.info_fifo,x[i]); + } + mke_log("\n"); + */ + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_READTOC: + CHECK_READY(); + fifo8_reset(&mke.info_fifo); + /* + mke_log("READ TOC:"); + for(i=0;i<6;i++) { + mke_log("%02x ",mke.command_buffer[i+1]); + } + mke_log(" | "); + */ + mke_read_toc(mke.cdrom_dev,(uint8_t *)&x,mke.command_buffer[2]); + fifo8_push_all(&mke.info_fifo, x, 8); + /* + for(i=0;i<8;i++) { + mke_log("%02x ",x[i]); + cdrom_fifo_write(&cdrom.info_fifo,x[i]); + } + */ + /* mke_log("\n"); */ + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_PLAY_MSF: + CHECK_READY(); + fifo8_reset(&mke.info_fifo); + mke_log("PLAY MSF:"); + for(i=0;i<6;i++) { + mke_log("%02x ",mke.command_buffer[i+1]); + } + mke_log("\n"); + //cdrom_audio_playmsf(&cdrom, + // mke.command_buffer[1], + // mke.command_buffer[2], + // mke.command_buffer[3], + // mke.command_buffer[4], + // mke.command_buffer[5], + // mke.command_buffer[6] + //); + { + int msf = 1; + int pos = (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3]; + int len = (mke.command_buffer[4] << 16) | (mke.command_buffer[5] << 8) | mke.command_buffer[6]; + if (!cdrom_audio_play(mke.cdrom_dev, pos, len, msf)) { + fifo8_push(&mke.errors_fifo, 0x0E); + fifo8_push(&mke.errors_fifo, 0x10); + } + } + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_SEEK: + CHECK_READY(); + old_cd_status = mke.cdrom_dev->cd_status; + fifo8_reset(&mke.info_fifo); + mke_log("SEEK MSF:"); //TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? + for(i=0;i<6;i++) { + mke_log("%02x ",mke.command_buffer[i+1]); + } + + cdrom_stop(mke.cdrom_dev); + cdrom_seek(mke.cdrom_dev, (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3], 0); + if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) { + cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, 0, -1); + cdrom_audio_pause_resume(mke.cdrom_dev, old_cd_status == CD_STATUS_PLAYING); + } + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_SESSINFO: + CHECK_READY(); + fifo8_reset(&mke.info_fifo); + mke_log("CMD: READ SESSION INFO\n"); + uint8_t session_info[6] = {0}; + fifo8_push_all(&mke.info_fifo, session_info, 6); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_READ_UPC: + CHECK_READY(); + fifo8_reset(&mke.info_fifo); + mke_log("CMD: READ UPC\n"); + uint8_t upc[8] = {[0] = 80}; + fifo8_push_all(&mke.info_fifo, upc, 8); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_READ_ERR: + fifo8_reset(&mke.info_fifo); + mke_log("CMD: READ ERR\n"); + //cdrom_read_errors(&cdrom,(uint8_t *)x); + memset(x, 0, 8); + if (fifo8_num_used(&mke.errors_fifo)) { + fifo8_pop_buf(&mke.errors_fifo, x, fifo8_num_used(&mke.errors_fifo)); + } + fifo8_push_all(&mke.info_fifo, x, 8); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_reset(&mke.errors_fifo); + break; + case CMD1_READ_VER: + /* + SB2CD Expects 12 bytes, but drive only returns 11. + */ + fifo8_reset(&mke.info_fifo); + mke_log("CMD: READ VER\n"); + uint8_t ver[10] = "CR-5631.02"; + fifo8_push_all(&mke.info_fifo, ver, 10); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + case CMD1_STATUS: + fifo8_reset(&mke.info_fifo); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + default: + mke_log("MKE: Unknown Commnad [%02x]\n",mke.command_buffer[0]); + } + } else if (!mke.command_buffer_pending) { //we are done byt not in a command. should we make sure it is a valid command here? + mke.command_buffer[0]=value; + mke.command_buffer_pending=6; + } +} + + +void MKE_WRITE(uint16_t address, uint8_t value, void* priv) { + pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value); + if(mke.enable_register && ((address & 0xF) != 3)) { + //mke_log("Ignore Write Unit %u\n",mke.enable_register); + return; + } + //mke_log("MKE WRITE: %02x => %03x\n",value,address); + switch(address & 0xF) { + case 0: + MKE_COMMAND(value); + break; + case 1: + mke.data_select=value; + break; + case 3: + mke.enable_register=value; + break; + default: + pclog("w %03x %02x\n", address, value); + break; + } +} + +uint8_t MKE_READ(uint16_t address, void* priv) { + uint8_t x; + if(mke.enable_register ) { + pclog("Ignore Read Unit %u\n",mke.enable_register); + return 0; + } + pclog("MKEREAD: 0x%X\n", address & 0xf); + switch(address & 0xF) { + case 0://Info + if(mke.data_select) { + return fifo8_pop(&mke.data_fifo); //cdrom_fifo_read(&cdrom.data_fifo); + } else { + return fifo8_pop(&mke.info_fifo); + //return cdrom_fifo_read(&cdrom.info_fifo); + } + break; + case 1://Status + /* + 1 = Status Change + 2 = Data Ready + 4 = Response Ready + 8 = Attention / Issue ? + */ + x=0xFF; + //if(cdrom.media_changed) x ^= 1; + if(fifo8_num_used(&mke.data_fifo)) x ^= 2;//DATA FIFO + if(fifo8_num_used(&mke.info_fifo)) x ^= 4;//STATUS FIFO + if(fifo8_num_used(&mke.errors_fifo)) x ^=8; + return x; + break; + case 2://Data + return fifo8_pop(&mke.data_fifo); + case 3: + return mke.enable_register; + break; + default: + /* mke_log("MKE Unknown Read Address: %03x\n",address); */ + pclog("MKE Unknown Read Address: %03x\n",address); + break; + } + return 0xff; +} + +void mke_close(void* priv) +{ + fifo8_destroy(&mke.info_fifo); + fifo8_destroy(&mke.data_fifo); + fifo8_destroy(&mke.errors_fifo); +} + +static void +mke_cdrom_insert(void *priv) +{ + mke_t *dev = (mke_t *)priv; + + if ((dev == NULL) || (dev->cdrom_dev == NULL)) + return; + + if (dev->cdrom_dev->ops == NULL) { + dev->unit_attention = 0; + dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; + fifo8_push(&dev->errors_fifo, 0x11); + } else if (dev->cdrom_dev->cd_status & CD_STATUS_TRANSITION) { + dev->unit_attention = 1; + /* Turn off the medium changed status. */ + dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION; + fifo8_push(&dev->errors_fifo, 0x11); + } else { + dev->unit_attention = 0; + dev->cdrom_dev->cd_status |= CD_STATUS_TRANSITION; + } +} + +void* mke_init(const device_t* info) +{ + cdrom_t* dev; + memset(&mke, 0, sizeof(mke_t)); + + for (int i = 0; i < CDROM_NUM; i++) { + if (cdrom[i].bus_type == CDROM_BUS_MKE) { + dev = &cdrom[i]; + break; + } + } + + if (!dev) + return NULL; + + fifo8_create(&mke.info_fifo, 128); + fifo8_create(&mke.data_fifo, 624240); + fifo8_create(&mke.errors_fifo, 8); + mke.cdrom_dev = dev; + mke.command_buffer_pending = 7; + mke.sector_type = 0x08 | (1 << 4); + mke.sector_flags = 0x10; + + dev->priv = &mke; + dev->insert = mke_cdrom_insert; + dev->cached_sector = -1; + dev->sector_size = 2048; + + io_sethandler(0x250, 16, MKE_READ, NULL, NULL, MKE_WRITE, NULL, NULL, &mke); + return &mke; +} + +const device_t mke_cdrom_device = { + .name = "Panasonic/MKE CD-ROM interface", + .internal_name = "mkecd", + .flags = DEVICE_ISA16, + .local = 0, + .init = mke_init, + .close = mke_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/config.c b/src/config.c index 9aa4a15e5..1ae07217b 100644 --- a/src/config.c +++ b/src/config.c @@ -898,6 +898,7 @@ load_storage_controllers(void) p = NULL; } + free_p = 0; p = ini_section_get_string(cat, "cdrom_interface", NULL); if (p != NULL) cdrom_interface_current = cdrom_interface_get_from_internal_name(p); @@ -2967,7 +2968,7 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_type", c + 1); char *tn = cdrom_get_internal_name(cdrom_get_type(c)); - if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || + if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || (cdrom[c].bus_type == CDROM_BUS_MKE) || !strcmp(tn, "86cd")) ini_section_delete_var(cat, temp); else diff --git a/src/disk/hdd.c b/src/disk/hdd.c index e051cc841..ddab10c97 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -78,6 +78,12 @@ no_cdrom: if (!strcmp(str, "scsi")) return HDD_BUS_SCSI; + + if (!strcmp(str, "mitsumi")) + return CDROM_BUS_MITSUMI; + + if (!strcmp(str, "mke")) + return CDROM_BUS_MKE; return 0; } @@ -89,6 +95,17 @@ hdd_bus_to_string(int bus, UNUSED(int cdrom)) switch (bus) { default: + if (cdrom) { + switch (bus) { + case CDROM_BUS_MITSUMI: + s = "mitsumi"; + break; + case CDROM_BUS_MKE: + s = "mke"; + break; + } + break; + } case HDD_BUS_DISABLED: break; diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index a031da199..8843f719e 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -97,7 +97,8 @@ enum { CDROM_BUS_ATAPI = 5, CDROM_BUS_SCSI = 6, CDROM_BUS_MITSUMI = 7, - CDROM_BUS_USB = 8 + CDROM_BUS_MKE = 8, + CDROM_BUS_USB = 9 }; #define BUS_TYPE_IDE CDROM_BUS_ATAPI diff --git a/src/include/86box/cdrom_mke.h b/src/include/86box/cdrom_mke.h new file mode 100644 index 000000000..f4f3ce13c --- /dev/null +++ b/src/include/86box/cdrom_mke.h @@ -0,0 +1,6 @@ +#ifndef CDROM_MKE_H +#define CDROM_MKE_H + +extern const device_t mke_cdrom_device; + +#endif /*CDROM_MITSUMI_H*/ \ No newline at end of file diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 52ae10a98..973b78820 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -52,15 +52,18 @@ Harddrives::populateRemovableBuses(QAbstractItemModel *model) { model->removeRows(0, model->rowCount()); #ifdef USE_CDROM_MITSUMI - model->insertRows(0, 4); + model->insertRows(0, 5); #else - model->insertRows(0, 3); + model->insertRows(0, 4); #endif model->setData(model->index(0, 0), QObject::tr("Disabled")); model->setData(model->index(1, 0), QObject::tr("ATAPI")); model->setData(model->index(2, 0), QObject::tr("SCSI")); #ifdef USE_CDROM_MITSUMI model->setData(model->index(3, 0), QObject::tr("Mitsumi")); + model->setData(model->index(4, 0), QObject::tr("Panasonic/MKE")); +#else + model->setData(model->index(3, 0), QObject::tr("Panasonic/MKE")); #endif model->setData(model->index(0, 0), HDD_BUS_DISABLED, Qt::UserRole); @@ -68,6 +71,9 @@ Harddrives::populateRemovableBuses(QAbstractItemModel *model) model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); #ifdef USE_CDROM_MITSUMI model->setData(model->index(3, 0), CDROM_BUS_MITSUMI, Qt::UserRole); + model->setData(model->index(4, 0), CDROM_BUS_MKE, Qt::UserRole); +#else + model->setData(model->index(3, 0), CDROM_BUS_MKE, Qt::UserRole); #endif } @@ -189,6 +195,9 @@ Harddrives::BusChannelName(uint8_t bus, uint8_t channel) case CDROM_BUS_MITSUMI: busName = QString("Mitsumi"); break; + case CDROM_BUS_MKE: + busName = QString("Panasonic/MKE"); + break; } return busName; diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 131b6ad6c..bc0439f3e 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -388,7 +388,7 @@ MachineStatus::iterateCDROM(const std::function &cb) (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; - if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI) && (cdrom_interface_current == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI || cdrom[i].bus_type == CDROM_BUS_MKE) && (cdrom_interface_current == 0)) continue; if (cdrom[i].bus_type != 0) { cb(i); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 2a0b3bbfd..8ad1c6fd6 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -834,8 +834,11 @@ MediaMenu::cdromUpdateMenu(int i) busName = "SCSI"; break; case CDROM_BUS_MITSUMI: - busName = "Mitsumi"; - break; + busName = "Mitsumi"; + break; + case CDROM_BUS_MKE: + busName = "Panasonic/MKE"; + break; } menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 6fb8637da..75c6dbbe5 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -23,10 +23,14 @@ #include "86box/hdd.h" #include "86box/scsi.h" +#include "86box/cdrom.h" #include "qt_settings_bus_tracking.hpp" SettingsBusTracking::SettingsBusTracking() { + mitsumi_tracking = false; + mke_tracking = false; + mfm_tracking = 0x0000000000000000ULL; esdi_tracking = 0x0000000000000000ULL; xta_tracking = 0x0000000000000000ULL; @@ -204,6 +208,14 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { int element; uint64_t mask; switch (bus) { + case CDROM_BUS_MKE: + if (mke_tracking) + channelsInUse.append(0); + break; + case CDROM_BUS_MITSUMI: + if (mitsumi_tracking) + channelsInUse.append(0); + break; case HDD_BUS_MFM: for (uint8_t i = 0; i < 32; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); @@ -263,6 +275,12 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe uint64_t mask; switch (bus) { + case CDROM_BUS_MKE: + mke_tracking = set; + break; + case CDROM_BUS_MITSUMI: + mitsumi_tracking = set; + break; case HDD_BUS_MFM: mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 917706428..96e997102 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -61,6 +61,8 @@ private: 8 bits per device (future-proofing) = 2048 bits. */ uint64_t scsi_tracking[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + bool mitsumi_tracking, mke_tracking; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index bf1499076..c88073ded 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -69,6 +69,7 @@ setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint case CDROM_BUS_ATAPI: case CDROM_BUS_SCSI: case CDROM_BUS_MITSUMI: + case CDROM_BUS_MKE: icon = QIcon(":/settings/qt/icons/cdrom.ico"); break; } @@ -104,7 +105,8 @@ setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type) auto i = idx.siblingAtColumn(2); 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) + else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI && + idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MKE) model->setData(i, CDROMName(type)); model->setData(i, type, Qt::UserRole); } @@ -175,7 +177,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) else if (cdrom[i].bus_type == CDROM_BUS_SCSI) Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].scsi_device_id); - else if (cdrom[i].bus_type == CDROM_BUS_MITSUMI) + else if (cdrom[i].bus_type == CDROM_BUS_MITSUMI || cdrom[i].bus_type == CDROM_BUS_MKE) Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, 0); } ui->tableViewCDROM->resizeColumnsToContents(); @@ -341,9 +343,9 @@ SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) if (index >= 0) { int bus = ui->comboBoxBus->currentData().toInt(); bool enabled = (bus != CDROM_BUS_DISABLED); - ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); + ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : enabled); + ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : enabled); + ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : enabled); Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus, Harddrives::busTrackClass); } @@ -370,7 +372,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_ide_channel()); else if (bus_type == CDROM_BUS_SCSI) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_scsi_id()); - else if (bus_type == CDROM_BUS_MITSUMI) + else if (bus_type == CDROM_BUS_MITSUMI || bus_type == CDROM_BUS_MKE) ui->comboBoxChannel->setCurrentIndex(0); setCDROMBus(ui->tableViewCDROM->model(), diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 8a810a4fb..6d6cbe928 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -114,6 +114,7 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) ui->setupUi(this); Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); + ui->comboBoxMOBus->model()->removeRows(3, ui->comboBoxMOBus->model()->rowCount() - 3); auto *model = ui->comboBoxMOType->model(); for (uint32_t i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { Models::AddEntry(model, moDriveTypeName(i), i); @@ -137,6 +138,7 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) ui->tableViewMO->setCurrentIndex(model->index(0, 0)); Harddrives::populateRemovableBuses(ui->comboBoxZIPBus->model()); + ui->comboBoxZIPBus->model()->removeRows(3, ui->comboBoxZIPBus->model()->rowCount() - 3); model = new QStandardItemModel(0, 2, this); ui->tableViewZIP->setModel(model); From 08250c3cbdc089902bb65c2874f8aabde0053f0f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 00:32:21 +0600 Subject: [PATCH 02/32] Fix some mistakes --- src/cdrom/cdrom_mke.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index f303fb607..0204385d4 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -95,7 +95,7 @@ mke_t mke; #define mke_log(x, ...) -#define CHECK_READY() { if (mke.cdrom_dev->image_path[0] == 0) { fifo8_push(&mke.errors_fifo, 0x03); return; } } +#define CHECK_READY() { if (mke.cdrom_dev->cd_status == CD_STATUS_EMPTY) { fifo8_push(&mke.errors_fifo, 0x03); return; } } static uint8_t temp_buf[65536]; @@ -175,22 +175,23 @@ uint8_t mke_disc_capacity(cdrom_t *dev, unsigned char *b) { } uint8_t mke_cdrom_status(cdrom_t *dev, mke_t* mke) { - uint8_t status = 0; + uint8_t status = 0; status |= 2;//this bit seems to always be set? //bit 4 never set? - if(dev->cd_status == CD_STATUS_PLAYING) status |= STAT_PLAY; - if(dev->cd_status == CD_STATUS_PAUSED) status |= STAT_PLAY; - if(fifo8_num_used(&mke->errors_fifo)) status |= 0x10; + if (dev->cd_status == CD_STATUS_PLAYING) status |= STAT_PLAY; + if (dev->cd_status == CD_STATUS_PAUSED) status |= STAT_PLAY; + if (fifo8_num_used(&mke->errors_fifo)) status |= 0x10; status |= 0x20;//always set? status |= STAT_TRAY; - if(dev->image_path[0] != 0) { - status |= STAT_DISK; + if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) { + status |= STAT_DISK; status |= STAT_READY; } return status; } +uint8_t ver[10] = "CR-5630.75"; void MKE_COMMAND(uint8_t value) { uint16_t i,len; uint8_t x[12];//this is wasteful handling of buffers for compatibility, but will optimize later. @@ -213,6 +214,7 @@ void MKE_COMMAND(uint8_t value) { } if (!mke.command_buffer_pending && mke.command_buffer[0]) { + mke.command_buffer_pending=7; switch (mke.command_buffer[0]) { case 06: { fifo8_reset(&mke.info_fifo); @@ -405,8 +407,7 @@ void MKE_COMMAND(uint8_t value) { SB2CD Expects 12 bytes, but drive only returns 11. */ fifo8_reset(&mke.info_fifo); - mke_log("CMD: READ VER\n"); - uint8_t ver[10] = "CR-5631.02"; + //pclog("CMD: READ VER\n"); fifo8_push_all(&mke.info_fifo, ver, 10); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; @@ -450,18 +451,20 @@ void MKE_WRITE(uint16_t address, uint8_t value, void* priv) { uint8_t MKE_READ(uint16_t address, void* priv) { uint8_t x; if(mke.enable_register ) { - pclog("Ignore Read Unit %u\n",mke.enable_register); + //pclog("Ignore Read Unit %u\n",mke.enable_register); return 0; } - pclog("MKEREAD: 0x%X\n", address & 0xf); + //pclog("MKEREAD: 0x%X\n", address & 0xf); switch(address & 0xF) { case 0://Info if(mke.data_select) { - return fifo8_pop(&mke.data_fifo); //cdrom_fifo_read(&cdrom.data_fifo); + x = fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; //cdrom_fifo_read(&cdrom.data_fifo); } else { - return fifo8_pop(&mke.info_fifo); + x = fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.info_fifo) : 0; //return cdrom_fifo_read(&cdrom.info_fifo); - } + } + //pclog("Read FIFO 0x%X, %d\n", x, mke.data_select); + return x; break; case 1://Status /* @@ -506,17 +509,14 @@ mke_cdrom_insert(void *priv) return; if (dev->cdrom_dev->ops == NULL) { - dev->unit_attention = 0; + //dev->unit_attention = 0; dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; fifo8_push(&dev->errors_fifo, 0x11); - } else if (dev->cdrom_dev->cd_status & CD_STATUS_TRANSITION) { - dev->unit_attention = 1; + } else { + //dev->unit_attention = 1; /* Turn off the medium changed status. */ dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION; fifo8_push(&dev->errors_fifo, 0x11); - } else { - dev->unit_attention = 0; - dev->cdrom_dev->cd_status |= CD_STATUS_TRANSITION; } } @@ -538,6 +538,9 @@ void* mke_init(const device_t* info) fifo8_create(&mke.info_fifo, 128); fifo8_create(&mke.data_fifo, 624240); fifo8_create(&mke.errors_fifo, 8); + fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke.data_fifo); + fifo8_reset(&mke.errors_fifo); mke.cdrom_dev = dev; mke.command_buffer_pending = 7; mke.sector_type = 0x08 | (1 << 4); From 5d7ff05c21aacb484bb44ed68ed0d6af19250980 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 00:51:33 +0600 Subject: [PATCH 03/32] Fix more missed stuff --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 0204385d4..34f31dd02 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -481,7 +481,7 @@ uint8_t MKE_READ(uint16_t address, void* priv) { return x; break; case 2://Data - return fifo8_pop(&mke.data_fifo); + return fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.data_fifo) : 0; case 3: return mke.enable_register; break; From 976516fa62d35bed7baf22c49440b83db82a79b0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 02:07:57 +0600 Subject: [PATCH 04/32] Fix reading more than 1 sector --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 34f31dd02..4b3bb9ee8 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -239,7 +239,7 @@ void MKE_COMMAND(uint8_t value) { uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]); CHECK_READY(); while (count) { - if ((res = cdrom_readsector_raw(mke.cdrom_dev, mke.cdbuffer, 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); lba++; buf += mke.cdrom_dev->sector_size; From 188b6da202f01c98217b41ea6784a196ba76b9da Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 25 Jul 2025 17:23:42 -0400 Subject: [PATCH 05/32] Whitespace cleanups, formatting, license headers --- src/cdrom/cdrom.c | 8 +- src/cdrom/cdrom_mke.c | 576 +++++++++++++++------------- src/include/86box/cdrom_mke.h | 19 +- src/qt/qt_mediamenu.cpp | 4 +- src/qt/qt_settings_bus_tracking.hpp | 3 +- 5 files changed, 340 insertions(+), 270 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index d051ef7ed..78506898a 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -120,12 +120,12 @@ static const struct { const device_t *device; } controllers[] = { // clang-format off - { &cdrom_interface_none_device }, + { &cdrom_interface_none_device }, #ifdef USE_CDROM_MITSUMI - { &mitsumi_cdrom_device }, + { &mitsumi_cdrom_device }, #endif - { &mke_cdrom_device }, - { NULL } + { &mke_cdrom_device }, + { NULL } // clang-format on }; diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 4b3bb9ee8..326c2100a 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -1,3 +1,19 @@ +/* + * 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. + * + * Mitsumi CD-ROM emulation for the ISA bus. + * + * Authors: Miran Grca, + * Cacodemon345 + * + * Copyright 2022-2025 Miran Grca. + * Copyright 2025 Cacodemon345. + */ #include #include #include @@ -21,7 +37,7 @@ /* https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h -CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix. +CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix. */ #define CDROM_STATUS_DOOR 0x80 #define CDROM_STATUS_DISC_IN 0x40 @@ -30,47 +46,45 @@ CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix. #define CDROM_STATUS_DOUBLE_SPEED 0x02 #define CDROM_STATUS_READY 0x01 - -//Status returned from device -#define STAT_READY 0x01 -#define STAT_PLAY 0x08 -#define STAT_ERROR 0x10 -#define STAT_DISK 0x40 -#define STAT_TRAY 0x80 //Seems Correct - +// Status returned from device +#define STAT_READY 0x01 +#define STAT_PLAY 0x08 +#define STAT_ERROR 0x10 +#define STAT_DISK 0x40 +#define STAT_TRAY 0x80 // Seems Correct #define CMD1_PAUSERESUME 0x0D -#define CMD1_RESET 0x0a -#define CMD1_LOCK_CTL 0x0c -#define CMD1_TRAY_CTL 0x07 -#define CMD1_MULTISESS 0x8d -#define CMD1_SUBCHANINF 0x11 -#define CMD1_ABORT 0x08 -//#define CMD1_PATH_CHECK 0x??? -#define CMD1_SEEK 0x01 -#define CMD1_READ 0x10 -#define CMD1_SPINUP 0x02 -#define CMD1_SPINDOWN 0x06 -#define CMD1_READ_UPC 0x88 -//#define CMD1_PLAY 0x??? -#define CMD1_PLAY_MSF 0x0e -#define CMD1_PLAY_TI 0x0f -#define CMD1_STATUS 0x05 -#define CMD1_READ_ERR 0x82 -#define CMD1_READ_VER 0x83 -#define CMD1_SETMODE 0x09 -#define CMD1_GETMODE 0x84 -#define CMD1_CAPACITY 0x85 -#define CMD1_READSUBQ 0x87 -#define CMD1_DISKINFO 0x8b -#define CMD1_READTOC 0x8c -#define CMD1_PAU_RES 0x0d -#define CMD1_PACKET 0x8e -#define CMD1_SESSINFO 0x8d +#define CMD1_RESET 0x0a +#define CMD1_LOCK_CTL 0x0c +#define CMD1_TRAY_CTL 0x07 +#define CMD1_MULTISESS 0x8d +#define CMD1_SUBCHANINF 0x11 +#define CMD1_ABORT 0x08 +// #define CMD1_PATH_CHECK 0x??? +#define CMD1_SEEK 0x01 +#define CMD1_READ 0x10 +#define CMD1_SPINUP 0x02 +#define CMD1_SPINDOWN 0x06 +#define CMD1_READ_UPC 0x88 +// #define CMD1_PLAY 0x??? +#define CMD1_PLAY_MSF 0x0e +#define CMD1_PLAY_TI 0x0f +#define CMD1_STATUS 0x05 +#define CMD1_READ_ERR 0x82 +#define CMD1_READ_VER 0x83 +#define CMD1_SETMODE 0x09 +#define CMD1_GETMODE 0x84 +#define CMD1_CAPACITY 0x85 +#define CMD1_READSUBQ 0x87 +#define CMD1_DISKINFO 0x8b +#define CMD1_READTOC 0x8c +#define CMD1_PAU_RES 0x0d +#define CMD1_PACKET 0x8e +#define CMD1_SESSINFO 0x8d typedef struct mke_t { - bool tray_open; - + bool tray_open; + uint8_t enable_register; uint8_t command_buffer[7]; @@ -78,14 +92,16 @@ typedef struct mke_t { uint8_t data_select; - uint8_t media_selected;//temporary hack + uint8_t media_selected; // temporary hack - Fifo8 data_fifo, info_fifo; + Fifo8 data_fifo; + Fifo8 info_fifo; Fifo8 errors_fifo; - cdrom_t* cdrom_dev; + cdrom_t *cdrom_dev; - uint32_t sector_type, sector_flags; + uint32_t sector_type; + uint32_t sector_flags; uint32_t unit_attention; @@ -95,93 +111,113 @@ mke_t mke; #define mke_log(x, ...) -#define CHECK_READY() { if (mke.cdrom_dev->cd_status == CD_STATUS_EMPTY) { fifo8_push(&mke.errors_fifo, 0x03); return; } } +#define CHECK_READY() \ + { \ + if (mke.cdrom_dev->cd_status == CD_STATUS_EMPTY) { \ + fifo8_push(&mke.errors_fifo, 0x03); \ + return; \ + } \ + } static uint8_t temp_buf[65536]; -void mke_get_subq(cdrom_t *dev,uint8_t *b) { - //dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - //cdrom_get_current_subchannel(dev, &subc); - //cdrom_get_current_subcodeq(dev, b); +void +mke_get_subq(cdrom_t *dev, uint8_t *b) +{ +#if 0 + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_current_subchannel(dev, &subc); + cdrom_get_current_subcodeq(dev, b); +#endif cdrom_get_current_subcodeq(dev, temp_buf); - b[0] = 0x80; //? - b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); - b[2] = temp_buf[1]; - b[3] = temp_buf[2]; - b[4] = temp_buf[6]; - b[5] = temp_buf[7]; - b[6] = temp_buf[8]; - b[7] = temp_buf[3]; - b[8] = temp_buf[4]; - b[9] = temp_buf[5]; - b[10]=0; //?? + b[0] = 0x80; //? + b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); + b[2] = temp_buf[1]; + b[3] = temp_buf[2]; + b[4] = temp_buf[6]; + b[5] = temp_buf[7]; + b[6] = temp_buf[8]; + b[7] = temp_buf[3]; + b[8] = temp_buf[4]; + b[9] = temp_buf[5]; + b[10] = 0; //?? } -uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { +uint8_t +mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) +{ track_info_t ti; - int first_track; - int last_track; - //dev->ops->get_tracks(dev, &first_track, &last_track); + int first_track; + int last_track; + // dev->ops->get_tracks(dev, &first_track, &last_track); cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); first_track = temp_buf[2]; - last_track = temp_buf[3]; - if(track > last_track) return 0; //should we allow +1 here? + last_track = temp_buf[3]; + if (track > last_track) + return 0; // should we allow +1 here? dev->ops->get_track_info(dev, track, 0, &ti); - b[0]=0x0; - b[1]=ti.attr; - b[2]=ti.number; - b[3]=0; - b[4]=ti.m; - b[5]=ti.s; - b[6]=ti.f; - b[7]=0; - return 1; - -} -uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { - track_info_t ti; - int first_track; - int last_track; - cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); - first_track = temp_buf[2]; - last_track = temp_buf[3]; - dev->ops->get_track_info(dev, last_track+1, 0, &ti); - b[0]=0x0; - b[1]=first_track; - b[2]=last_track; - b[3]=ti.m; - b[4]=ti.s; - b[5]=ti.f; - return 1; - + b[0] = 0x0; + b[1] = ti.attr; + b[2] = ti.number; + b[3] = 0; + b[4] = ti.m; + b[5] = ti.s; + b[6] = ti.f; + b[7] = 0; + return 1; } -uint8_t mke_disc_capacity(cdrom_t *dev, unsigned char *b) { +uint8_t +mke_disc_info(cdrom_t *dev, unsigned char *b) +{ track_info_t ti; - int first_track; - int last_track; - //dev->ops->get_tracks(dev, &first_track, &last_track); + int first_track; + int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); first_track = temp_buf[2]; - last_track = temp_buf[3]; - dev->ops->get_track_info(dev, last_track+1, 0, &ti); - b[0]=ti.m; - b[1]=ti.s; - b[2]=ti.f-1; //TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM - b[3]=0x08; - b[4]=0x00; - return 1; - + last_track = temp_buf[3]; + dev->ops->get_track_info(dev, last_track + 1, 0, &ti); + b[0] = 0x0; + b[1] = first_track; + b[2] = last_track; + b[3] = ti.m; + b[4] = ti.s; + b[5] = ti.f; + return 1; } -uint8_t mke_cdrom_status(cdrom_t *dev, mke_t* mke) { +uint8_t +mke_disc_capacity(cdrom_t *dev, unsigned char *b) +{ + track_info_t ti; + int first_track; + int last_track; + // dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + first_track = temp_buf[2]; + last_track = temp_buf[3]; + dev->ops->get_track_info(dev, last_track + 1, 0, &ti); + b[0] = ti.m; + b[1] = ti.s; + b[2] = ti.f - 1; // TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM + b[3] = 0x08; + b[4] = 0x00; + return 1; +} + +uint8_t +mke_cdrom_status(cdrom_t *dev, mke_t *mke) +{ uint8_t status = 0; - status |= 2;//this bit seems to always be set? - //bit 4 never set? - if (dev->cd_status == CD_STATUS_PLAYING) status |= STAT_PLAY; - if (dev->cd_status == CD_STATUS_PAUSED) status |= STAT_PLAY; - if (fifo8_num_used(&mke->errors_fifo)) status |= 0x10; - status |= 0x20;//always set? + status |= 2; // this bit seems to always be set? + // bit 4 never set? + if (dev->cd_status == CD_STATUS_PLAYING) + status |= STAT_PLAY; + if (dev->cd_status == CD_STATUS_PAUSED) + status |= STAT_PLAY; + if (fifo8_num_used(&mke->errors_fifo)) + status |= 0x10; + status |= 0x20; // always set? status |= STAT_TRAY; if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) { status |= STAT_DISK; @@ -192,93 +228,99 @@ uint8_t mke_cdrom_status(cdrom_t *dev, mke_t* mke) { } uint8_t ver[10] = "CR-5630.75"; -void MKE_COMMAND(uint8_t value) { - uint16_t i,len; - uint8_t x[12];//this is wasteful handling of buffers for compatibility, but will optimize later. - subchannel_t subc; - int old_cd_status; - if(mke.command_buffer_pending) { - mke.command_buffer[6-mke.command_buffer_pending+1]=value; - mke.command_buffer_pending--; +void +mke_command(uint8_t value) +{ + uint16_t i, len; + uint8_t x[12]; // this is wasteful handling of buffers for compatibility, but will optimize later. + subchannel_t subc; + int old_cd_status; + + if (mke.command_buffer_pending) { + mke.command_buffer[6 - mke.command_buffer_pending + 1] = value; + mke.command_buffer_pending--; } - if(mke.command_buffer[0] == CMD1_ABORT) { + if (mke.command_buffer[0] == CMD1_ABORT) { mke_log("CMD_ABORT\n"); - //fifo8_reset(&mke.info_fifo); + // fifo8_reset(&mke.info_fifo); fifo8_reset(&mke.info_fifo); - mke.command_buffer[0]=0; - mke.command_buffer_pending=7; - //fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + mke.command_buffer[0] = 0; + 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)); } if (!mke.command_buffer_pending && mke.command_buffer[0]) { - mke.command_buffer_pending=7; + mke.command_buffer_pending = 7; switch (mke.command_buffer[0]) { - case 06: { - fifo8_reset(&mke.info_fifo); - cdrom_stop(mke.cdrom_dev); - cdrom_eject(mke.cdrom_dev->id); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - break; - } - case 07: { - fifo8_reset(&mke.info_fifo); - cdrom_reload(mke.cdrom_dev->id); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - break; - } - case CMD1_READ: { - //cdrom_readsector_raw(mke.cdrom_dev, ) - uint32_t count = mke.command_buffer[6]; - uint8_t* buf = mke.cdbuffer; - int len = 0; - int res = 0; - int error = 0; - uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]); - CHECK_READY(); - while (count) { - 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); - lba++; - buf += mke.cdrom_dev->sector_size; - } else { - fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); - break; + case 06: + { + fifo8_reset(&mke.info_fifo); + cdrom_stop(mke.cdrom_dev); + cdrom_eject(mke.cdrom_dev->id); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + } + case 07: + { + fifo8_reset(&mke.info_fifo); + cdrom_reload(mke.cdrom_dev->id); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + break; + } + case CMD1_READ: + { + // cdrom_readsector_raw(mke.cdrom_dev, ) + uint32_t count = mke.command_buffer[6]; + uint8_t *buf = mke.cdbuffer; + int len = 0; + int res = 0; + int error = 0; + uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]); + CHECK_READY(); + while (count) { + 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); + lba++; + buf += mke.cdrom_dev->sector_size; + } else { + fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); + break; + } + count--; } - count--; + if (count != 0) { + fifo8_reset(&mke.data_fifo); + } + break; } - if (count != 0) { - fifo8_reset(&mke.data_fifo); - } - break; - } case CMD1_READSUBQ: CHECK_READY(); - mke_get_subq(mke.cdrom_dev, (uint8_t *)&x); + mke_get_subq(mke.cdrom_dev, (uint8_t *) &x); fifo8_reset(&mke.info_fifo); - //fifo8_push_all(&cdrom.info_fifo, x, 11); + // fifo8_push_all(&cdrom.info_fifo, x, 11); fifo8_push_all(&mke.info_fifo, x, 11); - /* - for(i=0;i<11;i++) { - cdrom_fifo_write(&cdrom.info_fifo,x[i]); +#if 0 + for (i=0; i < 11; i++) { + cdrom_fifo_write(&cdrom.info_fifo,x[i]); } - */ +#endif fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; - case CMD1_SETMODE: //Returns 1 + case CMD1_SETMODE: // Returns 1 fifo8_reset(&mke.info_fifo); mke_log("CMD: SET MODE:"); - for(i=0;i<6;i++) { - mke_log("%02x ",mke.command_buffer[i+1]); + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke.command_buffer[i + 1]); } mke_log("\n"); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; - case CMD1_GETMODE://6 + case CMD1_GETMODE: // 6 mke_log("GET MODE\n"); - uint8_t mode[5] = {[1] = 0x08}; + uint8_t mode[5] = { [1] = 0x08 }; fifo8_push_all(&mke.info_fifo, mode, 5); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; @@ -287,65 +329,67 @@ void MKE_COMMAND(uint8_t value) { cdrom_audio_pause_resume(mke.cdrom_dev, mke.command_buffer[1] >> 7); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; - case CMD1_CAPACITY://6 + case CMD1_CAPACITY: // 6 mke_log("DISK CAPACITY\n"); CHECK_READY(); - mke_disc_capacity(mke.cdrom_dev, (uint8_t *)&x); - //fifo8_push_all(&cdrom.info_fifo, x, 5); + mke_disc_capacity(mke.cdrom_dev, (uint8_t *) &x); + // fifo8_push_all(&cdrom.info_fifo, x, 5); fifo8_push_all(&mke.info_fifo, x, 5); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; - case CMD1_DISKINFO: //7 + case CMD1_DISKINFO: // 7 mke_log("DISK INFO\n"); CHECK_READY(); - mke_disc_info(mke.cdrom_dev, (uint8_t *)&x); + mke_disc_info(mke.cdrom_dev, (uint8_t *) &x); fifo8_push_all(&mke.info_fifo, x, 6); - /* - for(i=0;i<6;i++) { +#if 0 + for (i=0; i<6; i++) { mke_log("%02x ",x[i]); cdrom_fifo_write(&cdrom.info_fifo,x[i]); } mke_log("\n"); - */ +#endif fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_READTOC: CHECK_READY(); fifo8_reset(&mke.info_fifo); - /* +#if 0 mke_log("READ TOC:"); - for(i=0;i<6;i++) { + for (i=0; i<6; i++) { mke_log("%02x ",mke.command_buffer[i+1]); } - mke_log(" | "); - */ - mke_read_toc(mke.cdrom_dev,(uint8_t *)&x,mke.command_buffer[2]); + mke_log(" | "); +#endif + mke_read_toc(mke.cdrom_dev, (uint8_t *) &x, mke.command_buffer[2]); fifo8_push_all(&mke.info_fifo, x, 8); - /* - for(i=0;i<8;i++) { +#if 0 + for (i=0; i<8; i++) { mke_log("%02x ",x[i]); cdrom_fifo_write(&cdrom.info_fifo,x[i]); } - */ - /* mke_log("\n"); */ + mke_log("\n"); +#endif fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_PLAY_MSF: CHECK_READY(); fifo8_reset(&mke.info_fifo); mke_log("PLAY MSF:"); - for(i=0;i<6;i++) { - mke_log("%02x ",mke.command_buffer[i+1]); + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke.command_buffer[i + 1]); } mke_log("\n"); - //cdrom_audio_playmsf(&cdrom, - // mke.command_buffer[1], - // mke.command_buffer[2], - // mke.command_buffer[3], - // mke.command_buffer[4], - // mke.command_buffer[5], - // mke.command_buffer[6] - //); +#if 0 + cdrom_audio_playmsf(&cdrom, + mke.command_buffer[1], + mke.command_buffer[2], + mke.command_buffer[3], + mke.command_buffer[4], + mke.command_buffer[5], + mke.command_buffer[6] + ); +#endif { int msf = 1; int pos = (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3]; @@ -361,11 +405,11 @@ void MKE_COMMAND(uint8_t value) { CHECK_READY(); old_cd_status = mke.cdrom_dev->cd_status; fifo8_reset(&mke.info_fifo); - mke_log("SEEK MSF:"); //TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? - for(i=0;i<6;i++) { - mke_log("%02x ",mke.command_buffer[i+1]); + mke_log("SEEK MSF:"); // TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke.command_buffer[i + 1]); } - + cdrom_stop(mke.cdrom_dev); cdrom_seek(mke.cdrom_dev, (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3], 0); if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) { @@ -373,12 +417,12 @@ void MKE_COMMAND(uint8_t value) { cdrom_audio_pause_resume(mke.cdrom_dev, old_cd_status == CD_STATUS_PLAYING); } fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - break; + break; case CMD1_SESSINFO: CHECK_READY(); - fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke.info_fifo); mke_log("CMD: READ SESSION INFO\n"); - uint8_t session_info[6] = {0}; + uint8_t session_info[6] = { 0 }; fifo8_push_all(&mke.info_fifo, session_info, 6); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; @@ -386,14 +430,14 @@ void MKE_COMMAND(uint8_t value) { CHECK_READY(); fifo8_reset(&mke.info_fifo); mke_log("CMD: READ UPC\n"); - uint8_t upc[8] = {[0] = 80}; + uint8_t upc[8] = { [0] = 80 }; fifo8_push_all(&mke.info_fifo, upc, 8); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_READ_ERR: - fifo8_reset(&mke.info_fifo); - mke_log("CMD: READ ERR\n"); - //cdrom_read_errors(&cdrom,(uint8_t *)x); + fifo8_reset(&mke.info_fifo); + mke_log("CMD: READ ERR\n"); + // cdrom_read_errors(&cdrom,(uint8_t *)x); memset(x, 0, 8); if (fifo8_num_used(&mke.errors_fifo)) { fifo8_pop_buf(&mke.errors_fifo, x, fifo8_num_used(&mke.errors_fifo)); @@ -401,99 +445,106 @@ void MKE_COMMAND(uint8_t value) { fifo8_push_all(&mke.info_fifo, x, 8); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); fifo8_reset(&mke.errors_fifo); - break; + break; case CMD1_READ_VER: /* SB2CD Expects 12 bytes, but drive only returns 11. */ fifo8_reset(&mke.info_fifo); - //pclog("CMD: READ VER\n"); + // pclog("CMD: READ VER\n"); fifo8_push_all(&mke.info_fifo, ver, 10); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_STATUS: - fifo8_reset(&mke.info_fifo); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_reset(&mke.info_fifo); + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; default: - mke_log("MKE: Unknown Commnad [%02x]\n",mke.command_buffer[0]); - } - } else if (!mke.command_buffer_pending) { //we are done byt not in a command. should we make sure it is a valid command here? - mke.command_buffer[0]=value; - mke.command_buffer_pending=6; + mke_log("MKE: Unknown Commnad [%02x]\n", mke.command_buffer[0]); + } + } else if (!mke.command_buffer_pending) { // we are done byt not in a command. should we make sure it is a valid command here? + mke.command_buffer[0] = value; + mke.command_buffer_pending = 6; } } - -void MKE_WRITE(uint16_t address, uint8_t value, void* priv) { +void +mke_write(uint16_t address, uint8_t value, void *priv) +{ pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value); - if(mke.enable_register && ((address & 0xF) != 3)) { - //mke_log("Ignore Write Unit %u\n",mke.enable_register); + if (mke.enable_register && ((address & 0xF) != 3)) { + // mke_log("Ignore Write Unit %u\n",mke.enable_register); return; } - //mke_log("MKE WRITE: %02x => %03x\n",value,address); - switch(address & 0xF) { + // mke_log("MKE WRITE: %02x => %03x\n",value,address); + switch (address & 0xF) { case 0: - MKE_COMMAND(value); + mke_command(value); break; - case 1: - mke.data_select=value; + case 1: + mke.data_select = value; break; case 3: - mke.enable_register=value; + mke.enable_register = value; break; default: pclog("w %03x %02x\n", address, value); break; - } + } } -uint8_t MKE_READ(uint16_t address, void* priv) { +uint8_t +mke_read(uint16_t address, void *priv) +{ uint8_t x; - if(mke.enable_register ) { - //pclog("Ignore Read Unit %u\n",mke.enable_register); + if (mke.enable_register) { + // pclog("Ignore Read Unit %u\n",mke.enable_register); return 0; } - //pclog("MKEREAD: 0x%X\n", address & 0xf); - switch(address & 0xF) { - case 0://Info - if(mke.data_select) { - x = fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; //cdrom_fifo_read(&cdrom.data_fifo); + // pclog("MKEREAD: 0x%X\n", address & 0xf); + switch (address & 0xF) { + case 0: // Info + if (mke.data_select) { + x = fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; // cdrom_fifo_read(&cdrom.data_fifo); } else { x = fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.info_fifo) : 0; - //return cdrom_fifo_read(&cdrom.info_fifo); + // return cdrom_fifo_read(&cdrom.info_fifo); } - //pclog("Read FIFO 0x%X, %d\n", x, mke.data_select); + // pclog("Read FIFO 0x%X, %d\n", x, mke.data_select); return x; break; - case 1://Status + case 1: // Status /* 1 = Status Change 2 = Data Ready 4 = Response Ready 8 = Attention / Issue ? */ - x=0xFF; - //if(cdrom.media_changed) x ^= 1; - if(fifo8_num_used(&mke.data_fifo)) x ^= 2;//DATA FIFO - if(fifo8_num_used(&mke.info_fifo)) x ^= 4;//STATUS FIFO - if(fifo8_num_used(&mke.errors_fifo)) x ^=8; - return x; + x = 0xFF; + // if(cdrom.media_changed) x ^= 1; + if (fifo8_num_used(&mke.data_fifo)) + x ^= 2; // DATA FIFO + if (fifo8_num_used(&mke.info_fifo)) + x ^= 4; // STATUS FIFO + if (fifo8_num_used(&mke.errors_fifo)) + x ^= 8; + return x; break; - case 2://Data + case 2: // Data return fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.data_fifo) : 0; case 3: return mke.enable_register; break; default: /* mke_log("MKE Unknown Read Address: %03x\n",address); */ - pclog("MKE Unknown Read Address: %03x\n",address); + pclog("MKE Unknown Read Address: %03x\n", address); break; } return 0xff; } -void mke_close(void* priv) +void +mke_close(void *priv) { fifo8_destroy(&mke.info_fifo); fifo8_destroy(&mke.data_fifo); @@ -503,26 +554,27 @@ void mke_close(void* priv) static void mke_cdrom_insert(void *priv) { - mke_t *dev = (mke_t *)priv; + mke_t *dev = (mke_t *) priv; if ((dev == NULL) || (dev->cdrom_dev == NULL)) return; if (dev->cdrom_dev->ops == NULL) { - //dev->unit_attention = 0; + // dev->unit_attention = 0; dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; fifo8_push(&dev->errors_fifo, 0x11); } else { - //dev->unit_attention = 1; + // dev->unit_attention = 1; /* Turn off the medium changed status. */ dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION; fifo8_push(&dev->errors_fifo, 0x11); } } -void* mke_init(const device_t* info) +void * +mke_init(const device_t *info) { - cdrom_t* dev; + cdrom_t *dev; memset(&mke, 0, sizeof(mke_t)); for (int i = 0; i < CDROM_NUM; i++) { @@ -541,17 +593,17 @@ void* mke_init(const device_t* info) fifo8_reset(&mke.info_fifo); fifo8_reset(&mke.data_fifo); fifo8_reset(&mke.errors_fifo); - mke.cdrom_dev = dev; + mke.cdrom_dev = dev; mke.command_buffer_pending = 7; - mke.sector_type = 0x08 | (1 << 4); - mke.sector_flags = 0x10; + mke.sector_type = 0x08 | (1 << 4); + mke.sector_flags = 0x10; - dev->priv = &mke; - dev->insert = mke_cdrom_insert; + dev->priv = &mke; + dev->insert = mke_cdrom_insert; dev->cached_sector = -1; - dev->sector_size = 2048; + dev->sector_size = 2048; - io_sethandler(0x250, 16, MKE_READ, NULL, NULL, MKE_WRITE, NULL, NULL, &mke); + io_sethandler(0x250, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); return &mke; } diff --git a/src/include/86box/cdrom_mke.h b/src/include/86box/cdrom_mke.h index f4f3ce13c..3c946246c 100644 --- a/src/include/86box/cdrom_mke.h +++ b/src/include/86box/cdrom_mke.h @@ -1,6 +1,23 @@ +/* + * 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. + * + * Panasonic/MKE CD-ROM emulation for the ISA bus. + * + * Authors: Miran Grca, + * Cacodemon345 + * + * Copyright 2022-2025 Miran Grca. + * Copyright 2025 Cacodemon345. + */ + #ifndef CDROM_MKE_H #define CDROM_MKE_H extern const device_t mke_cdrom_device; -#endif /*CDROM_MITSUMI_H*/ \ No newline at end of file +#endif /*CDROM_MKE_H*/ diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 4e50720f6..0e5dea4d7 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -834,8 +834,8 @@ MediaMenu::cdromUpdateMenu(int i) busName = "SCSI"; break; case CDROM_BUS_MITSUMI: - busName = "Mitsumi"; - break; + busName = "Mitsumi"; + break; case CDROM_BUS_MKE: busName = "Panasonic/MKE"; break; diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 7e3bf77dc..26eaccae0 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -62,7 +62,8 @@ private: uint64_t scsi_tracking[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - bool mitsumi_tracking, mke_tracking; + bool mitsumi_tracking; + bool mke_tracking; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP From c959c9263afb6e07a3610f5d79406b1ea8d94354 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 25 Jul 2025 17:33:36 -0400 Subject: [PATCH 06/32] Add I/O Config --- src/cdrom/cdrom_mke.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 326c2100a..4e1d188b3 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -603,10 +603,35 @@ mke_init(const device_t *info) dev->cached_sector = -1; dev->sector_size = 2048; - io_sethandler(0x250, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); + uint16_t base = device_get_config_hex16("base"); + io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); return &mke; } +static const device_config_t mke_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x250, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "230H", .value = 0x230 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { .description = "270H", .value = 0x270 }, + { .description = "290H", .value = 0x290 }, + { NULL } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + const device_t mke_cdrom_device = { .name = "Panasonic/MKE CD-ROM interface", .internal_name = "mkecd", @@ -618,5 +643,5 @@ const device_t mke_cdrom_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = mke_config }; From 643590893c9aa9d1acf1aede51099ab015e9b6a5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 17:19:56 +0600 Subject: [PATCH 07/32] More Panasonic/MKE updates --- src/cdrom/cdrom_mke.c | 68 +++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 4e1d188b3..2c39f2f81 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -141,48 +141,62 @@ mke_get_subq(cdrom_t *dev, uint8_t *b) b[8] = temp_buf[4]; b[9] = temp_buf[5]; b[10] = 0; //?? + pclog("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); } -uint8_t -mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) +// Lifted from FreeBSD + +static void blk_to_msf(int blk, unsigned char *msf) { + blk = blk + 150; /*2 seconds skip required to + reach ISO data*/ + msf[0] = blk / 4500; + blk = blk % 4500; + msf[1] = blk / 75; + msf[2] = blk % 75; + return; +} + +uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { track_info_t ti; - int first_track; - int last_track; - // dev->ops->get_tracks(dev, &first_track, &last_track); + int first_track; + int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); first_track = temp_buf[2]; - last_track = temp_buf[3]; - if (track > last_track) - return 0; // should we allow +1 here? - dev->ops->get_track_info(dev, track, 0, &ti); - b[0] = 0x0; - b[1] = ti.attr; - b[2] = ti.number; - b[3] = 0; - b[4] = ti.m; - b[5] = ti.s; - b[6] = ti.f; - b[7] = 0; - return 1; + last_track = temp_buf[3]; + if(track > last_track) return 0; //should we allow +1 here? + dev->ops->get_track_info(dev->local, track, 0, &ti); + b[0]=0; + b[1]=ti.attr; + b[2]=ti.number; + b[3]=0; + b[4]=ti.m; + b[5]=ti.s; + b[6]=ti.f; + b[7]=0; + pclog("mke_read_toc: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + return 1; } + uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { track_info_t ti; int first_track; int last_track; - cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); first_track = temp_buf[2]; last_track = temp_buf[3]; - dev->ops->get_track_info(dev, last_track + 1, 0, &ti); + // dev->ops->get_track_info(dev, last_track + 1, 0, &ti); b[0] = 0x0; b[1] = first_track; b[2] = last_track; - b[3] = ti.m; - b[4] = ti.s; - b[5] = ti.f; + b[3] = 0; + b[4] = 0; + b[5] = 0; + blk_to_msf(dev->cdrom_capacity, &b[3]); + pclog("mke_disc_info: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5]); return 1; } @@ -193,7 +207,7 @@ mke_disc_capacity(cdrom_t *dev, unsigned char *b) int first_track; int last_track; // dev->ops->get_tracks(dev, &first_track, &last_track); - cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); first_track = temp_buf[2]; last_track = temp_buf[3]; dev->ops->get_track_info(dev, last_track + 1, 0, &ti); @@ -202,6 +216,9 @@ mke_disc_capacity(cdrom_t *dev, unsigned char *b) b[2] = ti.f - 1; // TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM b[3] = 0x08; b[4] = 0x00; + + blk_to_msf(dev->cdrom_capacity, &b[0]); + pclog("mke_disc_capacity: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4]); return 1; } @@ -254,6 +271,7 @@ mke_command(uint8_t value) if (!mke.command_buffer_pending && mke.command_buffer[0]) { mke.command_buffer_pending = 7; + pclog("mke_command: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", mke.command_buffer[0], mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3], mke.command_buffer[4], mke.command_buffer[5], mke.command_buffer[6]); switch (mke.command_buffer[0]) { case 06: { @@ -471,7 +489,7 @@ mke_command(uint8_t value) void mke_write(uint16_t address, uint8_t value, void *priv) { - pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value); + //pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value); if (mke.enable_register && ((address & 0xF) != 3)) { // mke_log("Ignore Write Unit %u\n",mke.enable_register); return; From 93785bd77c3001b441cc47caac480901d05659d9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 21:17:32 +0600 Subject: [PATCH 08/32] Fix LBA offset calculation --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 2c39f2f81..6f3479c16 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -296,7 +296,7 @@ mke_command(uint8_t value) int len = 0; int res = 0; int error = 0; - uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]); + uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150; CHECK_READY(); while (count) { if ((res = cdrom_readsector_raw(mke.cdrom_dev, buf, lba, 0, mke.sector_type, mke.sector_flags, &len, 0)) > 0) { From baae7b185c5f7cd3487d2ac0c4c5a88210dc57b8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 21:52:50 +0600 Subject: [PATCH 09/32] Fix reading on CDMKE driver --- src/cdrom/cdrom_mke.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 6f3479c16..59293c98f 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -311,6 +311,8 @@ mke_command(uint8_t value) } if (count != 0) { fifo8_reset(&mke.data_fifo); + } else { + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); } break; } From ab838a4f9339fc26a223bb75b41580db62bce242 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 22:27:25 +0600 Subject: [PATCH 10/32] Audio tracks now listed properly --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 59293c98f..931975c28 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -131,7 +131,7 @@ mke_get_subq(cdrom_t *dev, uint8_t *b) #endif cdrom_get_current_subcodeq(dev, temp_buf); b[0] = 0x80; //? - b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); + b[1] = temp_buf[0]; b[2] = temp_buf[1]; b[3] = temp_buf[2]; b[4] = temp_buf[6]; From 9268557c3dd2ac1d11afdd6416f596a333069a36 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 22:41:22 +0600 Subject: [PATCH 11/32] Fix seek commands for MKE --- src/cdrom/cdrom_mke.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 931975c28..177b35adc 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -417,9 +417,10 @@ mke_command(uint8_t value) if (!cdrom_audio_play(mke.cdrom_dev, pos, len, msf)) { fifo8_push(&mke.errors_fifo, 0x0E); fifo8_push(&mke.errors_fifo, 0x10); + } 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)); break; case CMD1_SEEK: CHECK_READY(); @@ -431,7 +432,8 @@ mke_command(uint8_t value) } cdrom_stop(mke.cdrom_dev); - cdrom_seek(mke.cdrom_dev, (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3], 0); + /* Note for self: Panasonic/MKE drives send seek commands in MSF format. */ + cdrom_seek(mke.cdrom_dev, MSFtoLBA((mke.command_buffer[1]), (mke.command_buffer[2]), mke.command_buffer[3]) - 150, 0); if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) { cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, 0, -1); cdrom_audio_pause_resume(mke.cdrom_dev, old_cd_status == CD_STATUS_PLAYING); From c32056b614566efeeb31f06e6c161873b35157d8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Jul 2025 23:22:51 +0600 Subject: [PATCH 12/32] Return "cooked" Q subchannel for Panasonic --- src/cdrom/cdrom_mke.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 177b35adc..8964fd611 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -129,9 +129,9 @@ mke_get_subq(cdrom_t *dev, uint8_t *b) cdrom_get_current_subchannel(dev, &subc); cdrom_get_current_subcodeq(dev, b); #endif - cdrom_get_current_subcodeq(dev, temp_buf); + cdrom_get_current_subchannel_sony(dev, temp_buf, 1); b[0] = 0x80; //? - b[1] = temp_buf[0]; + b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); b[2] = temp_buf[1]; b[3] = temp_buf[2]; b[4] = temp_buf[6]; @@ -290,7 +290,6 @@ mke_command(uint8_t value) } case CMD1_READ: { - // cdrom_readsector_raw(mke.cdrom_dev, ) uint32_t count = mke.command_buffer[6]; uint8_t *buf = mke.cdbuffer; int len = 0; @@ -433,9 +432,9 @@ mke_command(uint8_t value) cdrom_stop(mke.cdrom_dev); /* Note for self: Panasonic/MKE drives send seek commands in MSF format. */ - cdrom_seek(mke.cdrom_dev, MSFtoLBA((mke.command_buffer[1]), (mke.command_buffer[2]), mke.command_buffer[3]) - 150, 0); + cdrom_seek(mke.cdrom_dev, MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150, 0); if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) { - cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, 0, -1); + cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, -1, 0); cdrom_audio_pause_resume(mke.cdrom_dev, old_cd_status == CD_STATUS_PLAYING); } fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); From bc1b5f63bc2dc77397df6e0da4d26af05ccbf7ca Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 01:42:12 +0600 Subject: [PATCH 13/32] Implement Mode Sense/Mode Select and volume controls --- src/cdrom/cdrom_mke.c | 95 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 6 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 8964fd611..442b90a80 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -6,13 +6,15 @@ * * This file is part of the 86Box distribution. * - * Mitsumi CD-ROM emulation for the ISA bus. + * Panasonic/MKE CD-ROM emulation for the ISA bus. * * Authors: Miran Grca, + * Kevin Moonlight, * Cacodemon345 * - * Copyright 2022-2025 Miran Grca. - * Copyright 2025 Cacodemon345. + * Copyright (C) 2025 Miran Grca. + * Copyright (C) 2025 Cacodemon345. + * Copyright (C) 2024 Kevin Moonlight. */ #include #include @@ -90,6 +92,9 @@ typedef struct mke_t { uint8_t command_buffer[7]; uint8_t command_buffer_pending; + uint8_t vol0, vol1, patch0, patch1; + uint8_t mode_select[5]; + uint8_t data_select; uint8_t media_selected; // temporary hack @@ -246,6 +251,21 @@ mke_cdrom_status(cdrom_t *dev, mke_t *mke) uint8_t ver[10] = "CR-5630.75"; +static void +mke_reset(void) +{ + cdrom_stop(mke.cdrom_dev); + mke.sector_type = 0x08 | (1 << 4); + mke.sector_flags = 0x10; + memset(mke.mode_select, 0, 5); + mke.mode_select[2] = 0x08; + mke.patch0 = 0x01; + mke.patch1 = 0x02; + mke.vol0 = 255; + mke.vol1 = 255; + mke.cdrom_dev->sector_size = 2048; +} + void mke_command(uint8_t value) { @@ -288,6 +308,11 @@ mke_command(uint8_t value) fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; } + case CMD1_RESET: + { + mke_reset(); + break; + } case CMD1_READ: { uint32_t count = mke.command_buffer[6]; @@ -335,12 +360,48 @@ mke_command(uint8_t value) mke_log("%02x ", mke.command_buffer[i + 1]); } mke_log("\n"); + switch (mke.command_buffer[1]) { + case 0: + { + switch (mke.command_buffer[2]) { + case 0x00: { + mke.sector_type = 0x08 | (1 << 4); + mke.sector_flags = 0x10; + mke.cdrom_dev->sector_size = 2048; + break; + } + case 0x82: { + mke.sector_type = 0x00; + mke.sector_flags = 0xf8; + mke.cdrom_dev->sector_size = 2352; + break; + } + default: { + fifo8_push(&mke.errors_fifo, 0x0e); + return; + } + } + + memcpy(mke.mode_select, &mke.command_buffer[2], 5); + } + case 5: { + mke.vol0 = mke.command_buffer[4]; + mke.vol1 = mke.command_buffer[6]; + mke.patch0 = mke.command_buffer[3]; + mke.patch1 = mke.command_buffer[5]; + break; + } + } fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_GETMODE: // 6 mke_log("GET MODE\n"); - uint8_t mode[5] = { [1] = 0x08 }; - fifo8_push_all(&mke.info_fifo, mode, 5); + if (mke.command_buffer[1] == 5) { + uint8_t volsettings[5] = { 0, mke.patch0, mke.vol0, mke.patch1, mke.vol1 }; + fifo8_push_all(&mke.info_fifo, volsettings, 5); + } + else + fifo8_push_all(&mke.info_fifo, mke.mode_select, 5); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_PAUSERESUME: @@ -505,6 +566,9 @@ mke_write(uint16_t address, uint8_t value, void *priv) case 1: mke.data_select = value; break; + case 2: + mke_reset(); + break; case 3: mke.enable_register = value; break; @@ -592,6 +656,18 @@ mke_cdrom_insert(void *priv) } } +uint32_t +mke_get_volume(void *priv, int channel) +{ + return channel == 0 ? mke.vol0 : mke.vol1; +} + +uint32_t +mke_get_channel(void *priv, int channel) +{ + return channel == 0 ? mke.patch0 : mke.patch1; +} + void * mke_init(const device_t *info) { @@ -618,11 +694,18 @@ mke_init(const device_t *info) mke.command_buffer_pending = 7; mke.sector_type = 0x08 | (1 << 4); mke.sector_flags = 0x10; + mke.mode_select[2] = 0x08; + mke.patch0 = 0x01; + mke.patch1 = 0x02; + mke.vol0 = 255; + mke.vol1 = 255; + dev->sector_size = 2048; dev->priv = &mke; dev->insert = mke_cdrom_insert; + dev->get_volume = mke_get_volume; + dev->get_channel = mke_get_channel; dev->cached_sector = -1; - dev->sector_size = 2048; uint16_t base = device_get_config_hex16("base"); io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); From 7392f81536c8a09672bbbc66cf3965e4e17c6479 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 02:17:55 +0600 Subject: [PATCH 14/32] Implement timer for reads from CD-ROM --- src/cdrom/cdrom_mke.c | 47 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 442b90a80..369f66255 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -34,8 +34,10 @@ #include <86box/cdrom_interface.h> #include <86box/cdrom_mke.h> #include <86box/plat.h> +#include <86box/ui.h> #include <86box/sound.h> #include <86box/fifo8.h> +#include <86box/timer.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; - uint8_t cdbuffer[624240]; + uint8_t cdbuffer[624240 * 2]; + + uint32_t data_to_push; + + pc_timer_t timer; } mke_t; mke_t mke; @@ -255,6 +261,7 @@ static void mke_reset(void) { cdrom_stop(mke.cdrom_dev); + timer_disable(&mke.timer); mke.sector_type = 0x08 | (1 << 4); mke.sector_flags = 0x10; memset(mke.mode_select, 0, 5); @@ -266,6 +273,24 @@ mke_reset(void) 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 mke_command(uint8_t value) { @@ -283,6 +308,8 @@ mke_command(uint8_t value) mke_log("CMD_ABORT\n"); // 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_pending = 7; // fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); @@ -322,11 +349,13 @@ mke_command(uint8_t value) int error = 0; uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150; CHECK_READY(); + mke.data_to_push = 0; while (count) { 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++; buf += mke.cdrom_dev->sector_size; + mke.data_to_push += mke.cdrom_dev->sector_size; } else { fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); break; @@ -335,8 +364,11 @@ mke_command(uint8_t value) } if (count != 0) { fifo8_reset(&mke.data_fifo); + mke.data_to_push = 0; } 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; } @@ -634,6 +666,7 @@ mke_close(void *priv) fifo8_destroy(&mke.info_fifo); fifo8_destroy(&mke.data_fifo); fifo8_destroy(&mke.errors_fifo); + timer_disable(&mke.timer); } static void @@ -647,6 +680,11 @@ mke_cdrom_insert(void *priv) if (dev->cdrom_dev->ops == NULL) { // dev->unit_attention = 0; 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); } else { // dev->unit_attention = 1; @@ -685,7 +723,7 @@ mke_init(const device_t *info) return NULL; 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_reset(&mke.info_fifo); fifo8_reset(&mke.data_fifo); @@ -707,6 +745,7 @@ mke_init(const device_t *info) dev->get_channel = mke_get_channel; dev->cached_sector = -1; + timer_add(&mke.timer, mke_command_callback, &mke, 0); uint16_t base = device_get_config_hex16("base"); io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); return &mke; From 4b9bab7a8f1cb6ba332ca9fb507477fa9db24b30 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 02:38:46 +0600 Subject: [PATCH 15/32] Implement disc type value and XA/User reading modes --- src/cdrom/cdrom_mke.c | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 369f66255..f4a7db0a9 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -193,14 +193,16 @@ uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { + uint8_t disc_type_buf[34]; track_info_t ti; int first_track; int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); + cdrom_read_disc_information(dev, disc_type_buf); first_track = temp_buf[2]; last_track = temp_buf[3]; // dev->ops->get_track_info(dev, last_track + 1, 0, &ti); - b[0] = 0x0; + b[0] = disc_type_buf[8]; b[1] = first_track; b[2] = last_track; b[3] = 0; @@ -396,13 +398,64 @@ mke_command(uint8_t value) case 0: { switch (mke.command_buffer[2]) { - case 0x00: { + case 0x00: /* Cooked */ { mke.sector_type = 0x08 | (1 << 4); mke.sector_flags = 0x10; mke.cdrom_dev->sector_size = 2048; break; } - case 0x82: { + case 0x81: /* XA */ + case 0x01: /* User */ { + uint32_t sector_size = (mke.command_buffer[3] << 8) | mke.command_buffer[4]; + if (!sector_size) { + fifo8_push(&mke.errors_fifo, 0x0e); + return; + } else { + switch (sector_size) { + case 2048: { + mke.sector_type = 0x08 | (1 << 4); + mke.sector_flags = 0x10; + mke.cdrom_dev->sector_size = 2048; + break; + } + case 2052: { + mke.sector_type = 0x18; + mke.sector_flags = 0x30; + mke.cdrom_dev->sector_size = 2052; + break; + } + case 2324: { + mke.sector_type = 0x1b; + mke.sector_flags = 0x18; + mke.cdrom_dev->sector_size = 2324; + break; + } + case 2336: { + mke.sector_type = 0x1c; + mke.sector_flags = 0x58; + mke.cdrom_dev->sector_size = 2336; + break; + } + case 2340: { + mke.sector_type = 0x18; + mke.sector_flags = 0x78; + mke.cdrom_dev->sector_size = 2340; + break; + } + case 2352: { + mke.sector_type = 0x00; + mke.sector_flags = 0xf8; + mke.cdrom_dev->sector_size = 2352; + break; + } + default: { + fifo8_push(&mke.errors_fifo, 0x0e); + return; + } + } + } + } + case 0x82: /* DA */ { mke.sector_type = 0x00; mke.sector_flags = 0xf8; mke.cdrom_dev->sector_size = 2352; From 8964adf245db9c04bda5cb4b038a0af30c15e92e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 02:59:20 +0600 Subject: [PATCH 16/32] Fix potential null issue --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index f4a7db0a9..66c9773ab 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -762,7 +762,7 @@ mke_get_channel(void *priv, int channel) void * mke_init(const device_t *info) { - cdrom_t *dev; + cdrom_t *dev = NULL; memset(&mke, 0, sizeof(mke_t)); for (int i = 0; i < CDROM_NUM; i++) { From fa3678648f12b63d9db9e3428d69d50fa4b4ac96 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 26 Jul 2025 17:03:23 -0400 Subject: [PATCH 17/32] int to uint8_t --- src/cdrom/cdrom_mke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 66c9773ab..bafce41f3 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -765,7 +765,7 @@ mke_init(const device_t *info) cdrom_t *dev = NULL; memset(&mke, 0, sizeof(mke_t)); - for (int i = 0; i < CDROM_NUM; i++) { + for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type == CDROM_BUS_MKE) { dev = &cdrom[i]; break; From 26d2bf314ce785eba7c85039cf8287060e7ad498 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 12:12:44 +0600 Subject: [PATCH 18/32] Warnings cleanup --- src/cdrom/cdrom_mke.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index bafce41f3..e8c3eac1e 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -170,10 +170,8 @@ static void blk_to_msf(int blk, unsigned char *msf) uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { track_info_t ti; - int first_track; int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); - first_track = temp_buf[2]; last_track = temp_buf[3]; if(track > last_track) return 0; //should we allow +1 here? dev->ops->get_track_info(dev->local, track, 0, &ti); @@ -194,7 +192,6 @@ uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { uint8_t disc_type_buf[34]; - track_info_t ti; int first_track; int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); @@ -217,11 +214,9 @@ uint8_t mke_disc_capacity(cdrom_t *dev, unsigned char *b) { track_info_t ti; - int first_track; int last_track; // dev->ops->get_tracks(dev, &first_track, &last_track); cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); - first_track = temp_buf[2]; last_track = temp_buf[3]; dev->ops->get_track_info(dev, last_track + 1, 0, &ti); b[0] = ti.m; @@ -296,9 +291,8 @@ mke_command_callback(void* priv) void mke_command(uint8_t value) { - uint16_t i, len; + uint16_t i; uint8_t x[12]; // this is wasteful handling of buffers for compatibility, but will optimize later. - subchannel_t subc; int old_cd_status; if (mke.command_buffer_pending) { @@ -346,10 +340,9 @@ mke_command(uint8_t value) { uint32_t count = mke.command_buffer[6]; uint8_t *buf = mke.cdbuffer; - int len = 0; int res = 0; - int error = 0; uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150; + int len __attribute__((unused)) = 0; CHECK_READY(); mke.data_to_push = 0; while (count) { From df02d59021eefdd2295e40d689d64436e1ba8777 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 12:55:10 +0600 Subject: [PATCH 19/32] Implement multisession and track/index play commands --- src/cdrom/cdrom_mke.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index e8c3eac1e..8238649a3 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -252,6 +252,23 @@ mke_cdrom_status(cdrom_t *dev, mke_t *mke) return status; } +void +mke_read_multisess(void) +{ + int len = cdrom_read_toc(mke.cdrom_dev, temp_buf, CD_TOC_SESSION, 0, 1, 65536); + if (len == 4) { + /* Single-session disc. */ + uint8_t no_multisess[4] = { 0x00, 0x00, 0x00, 0x00 }; + fifo8_push_all(&mke.info_fifo, no_multisess, 4); + } else { + /* Multi-session disc. */ + fifo8_push(&mke.info_fifo, 0x80); + fifo8_push(&mke.info_fifo, temp_buf[9]); + fifo8_push(&mke.info_fifo, temp_buf[10]); + fifo8_push(&mke.info_fifo, temp_buf[11]); + } +} + uint8_t ver[10] = "CR-5630.75"; static void @@ -530,6 +547,19 @@ mke_command(uint8_t value) #endif fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; + case CMD1_PLAY_TI: + { + CHECK_READY(); + /* Index is ignored for now. */ + fifo8_reset(&mke.info_fifo); + if (!cdrom_audio_play(mke.cdrom_dev, mke.command_buffer[1], mke.command_buffer[3], 2)) { + fifo8_push(&mke.errors_fifo, 0x0E); + fifo8_push(&mke.errors_fifo, 0x10); + } else { + fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + } + break; + } case CMD1_PLAY_MSF: CHECK_READY(); fifo8_reset(&mke.info_fifo); @@ -582,8 +612,7 @@ mke_command(uint8_t value) CHECK_READY(); fifo8_reset(&mke.info_fifo); mke_log("CMD: READ SESSION INFO\n"); - uint8_t session_info[6] = { 0 }; - fifo8_push_all(&mke.info_fifo, session_info, 6); + mke_read_multisess(); fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; case CMD1_READ_UPC: From 0b8ff1d6a0acfd06076fee4ff3c5c1b90f415b76 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 14:02:37 +0600 Subject: [PATCH 20/32] Return reads from MKE offset 0x2 correctly --- src/cdrom/cdrom_mke.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 8238649a3..1bffa8106 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -723,7 +723,7 @@ mke_read(uint16_t address, void *priv) return x; break; case 2: // Data - return fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.data_fifo) : 0; + return fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; case 3: return mke.enable_register; break; @@ -851,7 +851,7 @@ static const device_config_t mke_config[] = { }; const device_t mke_cdrom_device = { - .name = "Panasonic/MKE CD-ROM interface", + .name = "Panasonic/MKE CD-ROM interface (Creative)", .internal_name = "mkecd", .flags = DEVICE_ISA16, .local = 0, @@ -863,3 +863,17 @@ const device_t mke_cdrom_device = { .force_redraw = NULL, .config = mke_config }; + +const device_t mke_cdrom_noncreative_device = { + .name = "Panasonic/MKE CD-ROM interface", + .internal_name = "mkecd_normal", + .flags = DEVICE_ISA16, + .local = 0, + .init = mke_init, + .close = mke_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mke_config +}; From c89283deefc85fa7f12748b1920d7145868b7514 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Jul 2025 14:31:13 +0600 Subject: [PATCH 21/32] Fix incorrect response length of multisession info command --- src/cdrom/cdrom_mke.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 1bffa8106..f57df031c 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -256,16 +256,17 @@ void mke_read_multisess(void) { int len = cdrom_read_toc(mke.cdrom_dev, temp_buf, CD_TOC_SESSION, 0, 1, 65536); - if (len == 4) { - /* Single-session disc. */ - uint8_t no_multisess[4] = { 0x00, 0x00, 0x00, 0x00 }; - fifo8_push_all(&mke.info_fifo, no_multisess, 4); - } else { + if (temp_buf[9] != 0 || temp_buf[10] != 0 || temp_buf[11] != 0) { /* Multi-session disc. */ fifo8_push(&mke.info_fifo, 0x80); fifo8_push(&mke.info_fifo, temp_buf[9]); fifo8_push(&mke.info_fifo, temp_buf[10]); fifo8_push(&mke.info_fifo, temp_buf[11]); + fifo8_push(&mke.info_fifo, 0); + fifo8_push(&mke.info_fifo, 0); + } else { + uint8_t no_multisess[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + fifo8_push_all(&mke.info_fifo, no_multisess, 6); } } From 029c2f5906620779e544515b45e00e7819cfd564 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 17:41:15 +0200 Subject: [PATCH 22/32] Reverting the change from build 7173. --- src/include/86box/vid_svga.h | 1 - src/video/vid_svga.c | 40 +++++++++++++++--------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 14f3c933a..5492da18a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -138,7 +138,6 @@ typedef struct svga_t { int ps_bit_bug; int ati_4color; int vblankend; - int panning_blank; int render_line_offset; int start_retrace_latch; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9d5841a94..0720910d6 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1443,8 +1443,10 @@ svga_poll(void *priv) svga->memaddr_backup = (svga->memaddr_backup << 2); svga->scanline = 0; - if (svga->attrregs[0x10] & 0x20) - svga->panning_blank = 1; + if (svga->attrregs[0x10] & 0x20) { + svga->scrollcache = 0; + svga->x_add = svga->left_overscan; + } } } if (svga->vc == svga->dispend) { @@ -1533,27 +1535,6 @@ svga_poll(void *priv) svga->scanline = (svga->crtc[0x8] & 0x1f); svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - - svga->linecountff = 0; - - svga->hwcursor_on = 0; - svga->hwcursor_latch = svga->hwcursor; - - svga->dac_hwcursor_on = 0; - svga->dac_hwcursor_latch = svga->dac_hwcursor; - - svga->overlay_on = 0; - svga->overlay_latch = svga->overlay; - - svga->panning_blank = 0; - } - - if (svga->scanline == (svga->crtc[10] & 31)) - svga->cursorvisible = 1; - - if (svga->panning_blank) { - svga->scrollcache = 0; - svga->x_add = svga->left_overscan; } else { svga->scrollcache = (svga->attrregs[0x13] & 0x0f); if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ @@ -1574,7 +1555,20 @@ svga_poll(void *priv) svga->scrollcache <<= 1; svga->x_add = svga->left_overscan - svga->scrollcache; + + svga->linecountff = 0; + + svga->hwcursor_on = 0; + svga->hwcursor_latch = svga->hwcursor; + + svga->dac_hwcursor_on = 0; + svga->dac_hwcursor_latch = svga->dac_hwcursor; + + svga->overlay_on = 0; + svga->overlay_latch = svga->overlay; } + if (svga->scanline == (svga->crtc[10] & 31)) + svga->cursorvisible = 1; } } From 0f8ec8d0e76f0d0ff70c81a1012b13960c67bab0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 17:49:00 +0200 Subject: [PATCH 23/32] Panasonic CD-ROM: Fix the only warning. --- src/cdrom/cdrom_mke.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index f57df031c..462e6ca36 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -255,8 +255,7 @@ mke_cdrom_status(cdrom_t *dev, mke_t *mke) void mke_read_multisess(void) { - int len = cdrom_read_toc(mke.cdrom_dev, temp_buf, CD_TOC_SESSION, 0, 1, 65536); - if (temp_buf[9] != 0 || temp_buf[10] != 0 || temp_buf[11] != 0) { + if ((temp_buf[9] != 0) || (temp_buf[10] != 0) || (temp_buf[11] != 0)) { /* Multi-session disc. */ fifo8_push(&mke.info_fifo, 0x80); fifo8_push(&mke.info_fifo, temp_buf[9]); From 9f35c6f97e2ceb503bff36a9dd59b30bf0455a5a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 17:52:10 +0200 Subject: [PATCH 24/32] Save the selected keyboard type and remove an excess logging line in keyboard.c. --- src/device/keyboard.c | 1 - src/qt/qt_settingsinput.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 02fbf0179..0acc93505 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -601,6 +601,5 @@ keyboard_get_ndev(void) void keyboard_add_device(void) { - pclog("keyboard_type = %i (%s)\n", keyboard_type, keyboard_get_internal_name(keyboard_type)); device_add(keyboard_devices[keyboard_type].device); } diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 1a425c835..6296cd1e9 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -91,7 +91,9 @@ SettingsInput::~SettingsInput() void SettingsInput::save() { + keyboard_type = ui->comboBoxKeyboard->currentData().toInt(); mouse_type = ui->comboBoxMouse->currentData().toInt(); + joystick_type = ui->comboBoxJoystick->currentData().toInt(); // Copy accelerators from working set to global set From b1b8ac639f3bd7a3f4cb576d57f4c0db648a948a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 17:53:35 +0200 Subject: [PATCH 25/32] Settings: Always enable the CD-ROM Interface selection. --- src/qt/qt_settingsstoragecontrollers.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index adf3994cb..35788bf18 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -108,15 +108,10 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxFD->setCurrentIndex(selectedRow); /*CD interface controller config*/ -#ifdef USE_CDROM_MITSUMI ui->labelCDInterface->setVisible(true); ui->comboBoxCDInterface->setVisible(true); ui->pushButtonCDInterface->setVisible(true); -#else - ui->labelCDInterface->setVisible(false); - ui->comboBoxCDInterface->setVisible(false); - ui->pushButtonCDInterface->setVisible(false); -#endif + c = 0; model = ui->comboBoxCDInterface->model(); removeRows = model->rowCount(); From 6016f6b9f1881bada3d6cb9fd512110331e9a45e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 18:43:55 +0200 Subject: [PATCH 26/32] MKE CD-ROM: Clean-up and actually use the instantiated pointer. --- src/cdrom/cdrom_mke.c | 749 ++++++++++++++++++++---------------------- 1 file changed, 365 insertions(+), 384 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 462e6ca36..f2a4e1a6e 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -98,6 +98,7 @@ typedef struct mke_t { uint8_t mode_select[5]; uint8_t data_select; + uint8_t is_sb; uint8_t media_selected; // temporary hack @@ -120,14 +121,32 @@ typedef struct mke_t { } mke_t; mke_t mke; -#define mke_log(x, ...) +static uint8_t ver[10] = "CR-5630.75"; + +#ifdef ENABLE_MKE_LOG +int mke_do_log = ENABLE_MKE_LOG; + +static void +mke_log(const char *fmt, ...) +{ + va_list ap; + + if (mke_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mke_log(fmt, ...) +#endif #define CHECK_READY() \ { \ - if (mke.cdrom_dev->cd_status == CD_STATUS_EMPTY) { \ - fifo8_push(&mke.errors_fifo, 0x03); \ - return; \ - } \ + if (mke->cdrom_dev->cd_status == CD_STATUS_EMPTY) { \ + fifo8_push(&mke->errors_fifo, 0x03); \ + return; \ + } \ } static uint8_t temp_buf[65536]; @@ -135,13 +154,9 @@ static uint8_t temp_buf[65536]; void mke_get_subq(cdrom_t *dev, uint8_t *b) { -#if 0 - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - cdrom_get_current_subchannel(dev, &subc); - cdrom_get_current_subcodeq(dev, b); -#endif cdrom_get_current_subchannel_sony(dev, temp_buf, 1); - b[0] = 0x80; //? + /* ? */ + b[0] = 0x80; b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4); b[2] = temp_buf[1]; b[3] = temp_buf[2]; @@ -151,21 +166,23 @@ mke_get_subq(cdrom_t *dev, uint8_t *b) b[7] = temp_buf[3]; b[8] = temp_buf[4]; b[9] = temp_buf[5]; - b[10] = 0; //?? + /* ? */ + b[10] = 0; pclog("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); } -// Lifted from FreeBSD +/* Lifted from FreeBSD */ static void blk_to_msf(int blk, unsigned char *msf) { - blk = blk + 150; /*2 seconds skip required to - reach ISO data*/ - msf[0] = blk / 4500; - blk = blk % 4500; - msf[1] = blk / 75; - msf[2] = blk % 75; - return; + blk = blk + 150; /* 2 seconds skip required to + reach ISO data */ + msf[0] = blk / 4500; + blk = blk % 4500; + msf[1] = blk / 75; + msf[2] = blk % 75; + + return; } uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { @@ -173,7 +190,9 @@ uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { int last_track; cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536); last_track = temp_buf[3]; - if(track > last_track) return 0; //should we allow +1 here? + /* Should we allow +1 here? */ + if (track > last_track) + return 0; dev->ops->get_track_info(dev->local, track, 0, &ti); b[0]=0; b[1]=ti.attr; @@ -183,7 +202,8 @@ uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) { b[5]=ti.s; b[6]=ti.f; b[7]=0; - pclog("mke_read_toc: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + mke_log("mke_read_toc: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); return 1; } @@ -192,13 +212,14 @@ uint8_t mke_disc_info(cdrom_t *dev, unsigned char *b) { uint8_t disc_type_buf[34]; - int first_track; - int last_track; + int first_track; + int last_track; + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); cdrom_read_disc_information(dev, disc_type_buf); first_track = temp_buf[2]; last_track = temp_buf[3]; - // dev->ops->get_track_info(dev, last_track + 1, 0, &ti); + b[0] = disc_type_buf[8]; b[1] = first_track; b[2] = last_track; @@ -206,7 +227,8 @@ mke_disc_info(cdrom_t *dev, unsigned char *b) b[4] = 0; b[5] = 0; blk_to_msf(dev->cdrom_capacity, &b[3]); - pclog("mke_disc_info: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5]); + mke_log("mke_disc_info: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5]); return 1; } @@ -215,18 +237,21 @@ mke_disc_capacity(cdrom_t *dev, unsigned char *b) { track_info_t ti; int last_track; - // dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); last_track = temp_buf[3]; dev->ops->get_track_info(dev, last_track + 1, 0, &ti); + b[0] = ti.m; b[1] = ti.s; - b[2] = ti.f - 1; // TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM + /* TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM */ + b[2] = ti.f - 1; b[3] = 0x08; b[4] = 0x00; blk_to_msf(dev->cdrom_capacity, &b[0]); - pclog("mke_disc_capacity: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4]); + mke_log("mke_disc_capacity: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4]); return 1; } @@ -234,15 +259,19 @@ uint8_t mke_cdrom_status(cdrom_t *dev, mke_t *mke) { uint8_t status = 0; - status |= 2; // this bit seems to always be set? - // bit 4 never set? + /* + This bit seems to always be set? + Bit 4 never set? + */ + status |= 2; if (dev->cd_status == CD_STATUS_PLAYING) status |= STAT_PLAY; if (dev->cd_status == CD_STATUS_PAUSED) status |= STAT_PLAY; if (fifo8_num_used(&mke->errors_fifo)) status |= 0x10; - status |= 0x20; // always set? + /* Always set? */ + status |= 0x20; status |= STAT_TRAY; if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) { status |= STAT_DISK; @@ -253,434 +282,384 @@ mke_cdrom_status(cdrom_t *dev, mke_t *mke) } void -mke_read_multisess(void) +mke_read_multisess(mke_t *mke) { if ((temp_buf[9] != 0) || (temp_buf[10] != 0) || (temp_buf[11] != 0)) { /* Multi-session disc. */ - fifo8_push(&mke.info_fifo, 0x80); - fifo8_push(&mke.info_fifo, temp_buf[9]); - fifo8_push(&mke.info_fifo, temp_buf[10]); - fifo8_push(&mke.info_fifo, temp_buf[11]); - fifo8_push(&mke.info_fifo, 0); - fifo8_push(&mke.info_fifo, 0); + fifo8_push(&mke->info_fifo, 0x80); + fifo8_push(&mke->info_fifo, temp_buf[9]); + fifo8_push(&mke->info_fifo, temp_buf[10]); + fifo8_push(&mke->info_fifo, temp_buf[11]); + fifo8_push(&mke->info_fifo, 0); + fifo8_push(&mke->info_fifo, 0); } else { uint8_t no_multisess[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - fifo8_push_all(&mke.info_fifo, no_multisess, 6); + fifo8_push_all(&mke->info_fifo, no_multisess, 6); } } -uint8_t ver[10] = "CR-5630.75"; - static void -mke_reset(void) +mke_reset(mke_t *mke) { - cdrom_stop(mke.cdrom_dev); - timer_disable(&mke.timer); - mke.sector_type = 0x08 | (1 << 4); - mke.sector_flags = 0x10; - memset(mke.mode_select, 0, 5); - mke.mode_select[2] = 0x08; - mke.patch0 = 0x01; - mke.patch1 = 0x02; - mke.vol0 = 255; - mke.vol1 = 255; - mke.cdrom_dev->sector_size = 2048; + cdrom_stop(mke->cdrom_dev); + timer_disable(&mke->timer); + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + memset(mke->mode_select, 0, 5); + mke->mode_select[2] = 0x08; + mke->patch0 = 0x01; + mke->patch1 = 0x02; + mke->vol0 = 255; + mke->vol1 = 255; + mke->cdrom_dev->sector_size = 2048; } void -mke_command_callback(void* priv) +mke_command_callback(void *priv) { - switch (mke.command_buffer[0]) { + mke_t *mke = (mke_t *) priv; + + switch (mke->command_buffer[0]) { case CMD1_SEEK: { - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + 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); + 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 -mke_command(uint8_t value) +mke_command(mke_t *mke, uint8_t value) { uint16_t i; - uint8_t x[12]; // this is wasteful handling of buffers for compatibility, but will optimize later. + /* This is wasteful handling of buffers for compatibility, but will optimize later. */ + uint8_t x[12]; int old_cd_status; - if (mke.command_buffer_pending) { - mke.command_buffer[6 - mke.command_buffer_pending + 1] = value; - mke.command_buffer_pending--; + if (mke->command_buffer_pending) { + mke->command_buffer[6 - mke->command_buffer_pending + 1] = value; + mke->command_buffer_pending--; } - if (mke.command_buffer[0] == CMD1_ABORT) { + if (mke->command_buffer[0] == CMD1_ABORT) { mke_log("CMD_ABORT\n"); - // 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_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)); + fifo8_reset(&mke->info_fifo); + fifo8_reset(&mke->data_fifo); + timer_disable(&mke->timer); + mke->command_buffer[0] = 0; + mke->command_buffer_pending = 7; + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); } - if (!mke.command_buffer_pending && mke.command_buffer[0]) { - mke.command_buffer_pending = 7; - pclog("mke_command: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", mke.command_buffer[0], mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3], mke.command_buffer[4], mke.command_buffer[5], mke.command_buffer[6]); - switch (mke.command_buffer[0]) { + if (!mke->command_buffer_pending && mke->command_buffer[0]) { + mke->command_buffer_pending = 7; + mke_log("mke_command: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + mke->command_buffer[0], mke->command_buffer[1], + mke->command_buffer[2], mke->command_buffer[3], + mke->command_buffer[4], mke->command_buffer[5], + mke->command_buffer[6]); + switch (mke->command_buffer[0]) { case 06: - { - fifo8_reset(&mke.info_fifo); - cdrom_stop(mke.cdrom_dev); - cdrom_eject(mke.cdrom_dev->id); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - break; - } + fifo8_reset(&mke->info_fifo); + cdrom_stop(mke->cdrom_dev); + cdrom_eject(mke->cdrom_dev->id); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; case 07: - { - fifo8_reset(&mke.info_fifo); - cdrom_reload(mke.cdrom_dev->id); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - break; - } + fifo8_reset(&mke->info_fifo); + cdrom_reload(mke->cdrom_dev->id); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; case CMD1_RESET: - { - mke_reset(); + mke_reset(mke); break; - } - case CMD1_READ: - { - uint32_t count = mke.command_buffer[6]; - uint8_t *buf = mke.cdbuffer; - int res = 0; - uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150; - int len __attribute__((unused)) = 0; - CHECK_READY(); - mke.data_to_push = 0; - while (count) { - 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); - lba++; - buf += mke.cdrom_dev->sector_size; - mke.data_to_push += mke.cdrom_dev->sector_size; - } else { - fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); - break; - } - count--; - } - if (count != 0) { - fifo8_reset(&mke.data_fifo); - mke.data_to_push = 0; - } else { - //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; - } - case CMD1_READSUBQ: + case CMD1_READ: { + uint32_t count = mke->command_buffer[6]; + uint8_t *buf = mke->cdbuffer; + int res = 0; + uint64_t lba = MSFtoLBA(mke->command_buffer[1], mke->command_buffer[2], + mke->command_buffer[3]) - 150; + int len __attribute__((unused)) = 0; + CHECK_READY(); - mke_get_subq(mke.cdrom_dev, (uint8_t *) &x); - fifo8_reset(&mke.info_fifo); - // fifo8_push_all(&cdrom.info_fifo, x, 11); - fifo8_push_all(&mke.info_fifo, x, 11); -#if 0 - for (i=0; i < 11; i++) { - cdrom_fifo_write(&cdrom.info_fifo,x[i]); + mke->data_to_push = 0; + + while (count) { + if ((res = cdrom_readsector_raw(mke->cdrom_dev, buf, lba, 0, + mke->sector_type, mke->sector_flags, &len, 0)) > 0) { + lba++; + buf += mke->cdrom_dev->sector_size; + mke->data_to_push += mke->cdrom_dev->sector_size; + } else { + fifo8_push(&mke->errors_fifo, res == 0 ? 0x10 : 0x05); + break; + } + count--; + } + if (count != 0) { + fifo8_reset(&mke->data_fifo); + mke->data_to_push = 0; + } else { + 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); } -#endif - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); break; - case CMD1_SETMODE: // Returns 1 - fifo8_reset(&mke.info_fifo); + } case CMD1_READSUBQ: + CHECK_READY(); + mke_get_subq(mke->cdrom_dev, (uint8_t *) &x); + fifo8_reset(&mke->info_fifo); + fifo8_push_all(&mke->info_fifo, x, 11); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_SETMODE: + /* Returns 1 */ + fifo8_reset(&mke->info_fifo); mke_log("CMD: SET MODE:"); for (i = 0; i < 6; i++) { - mke_log("%02x ", mke.command_buffer[i + 1]); + mke_log("%02x ", mke->command_buffer[i + 1]); } mke_log("\n"); - switch (mke.command_buffer[1]) { + switch (mke->command_buffer[1]) { case 0: - { - switch (mke.command_buffer[2]) { - case 0x00: /* Cooked */ { - mke.sector_type = 0x08 | (1 << 4); - mke.sector_flags = 0x10; - mke.cdrom_dev->sector_size = 2048; + switch (mke->command_buffer[2]) { + case 0x00: /* Cooked */ + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->cdrom_dev->sector_size = 2048; break; - } case 0x81: /* XA */ case 0x01: /* User */ { - uint32_t sector_size = (mke.command_buffer[3] << 8) | mke.command_buffer[4]; + uint32_t sector_size = (mke->command_buffer[3] << 8) | + mke->command_buffer[4]; + if (!sector_size) { - fifo8_push(&mke.errors_fifo, 0x0e); + fifo8_push(&mke->errors_fifo, 0x0e); return; } else { switch (sector_size) { - case 2048: { - mke.sector_type = 0x08 | (1 << 4); - mke.sector_flags = 0x10; - mke.cdrom_dev->sector_size = 2048; + case 2048: + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->cdrom_dev->sector_size = 2048; break; - } - case 2052: { - mke.sector_type = 0x18; - mke.sector_flags = 0x30; - mke.cdrom_dev->sector_size = 2052; + case 2052: + mke->sector_type = 0x18; + mke->sector_flags = 0x30; + mke->cdrom_dev->sector_size = 2052; break; - } - case 2324: { - mke.sector_type = 0x1b; - mke.sector_flags = 0x18; - mke.cdrom_dev->sector_size = 2324; + case 2324: + mke->sector_type = 0x1b; + mke->sector_flags = 0x18; + mke->cdrom_dev->sector_size = 2324; break; - } - case 2336: { - mke.sector_type = 0x1c; - mke.sector_flags = 0x58; - mke.cdrom_dev->sector_size = 2336; + case 2336: + mke->sector_type = 0x1c; + mke->sector_flags = 0x58; + mke->cdrom_dev->sector_size = 2336; break; - } - case 2340: { - mke.sector_type = 0x18; - mke.sector_flags = 0x78; - mke.cdrom_dev->sector_size = 2340; + case 2340: + mke->sector_type = 0x18; + mke->sector_flags = 0x78; + mke->cdrom_dev->sector_size = 2340; break; - } - case 2352: { - mke.sector_type = 0x00; - mke.sector_flags = 0xf8; - mke.cdrom_dev->sector_size = 2352; + case 2352: + mke->sector_type = 0x00; + mke->sector_flags = 0xf8; + mke->cdrom_dev->sector_size = 2352; break; - } - default: { - fifo8_push(&mke.errors_fifo, 0x0e); + default: + fifo8_push(&mke->errors_fifo, 0x0e); return; - } } } - } - case 0x82: /* DA */ { - mke.sector_type = 0x00; - mke.sector_flags = 0xf8; - mke.cdrom_dev->sector_size = 2352; break; - } - default: { - fifo8_push(&mke.errors_fifo, 0x0e); + } case 0x82: /* DA */ + mke->sector_type = 0x00; + mke->sector_flags = 0xf8; + mke->cdrom_dev->sector_size = 2352; + break; + default: + fifo8_push(&mke->errors_fifo, 0x0e); return; - } } - memcpy(mke.mode_select, &mke.command_buffer[2], 5); - } - case 5: { - mke.vol0 = mke.command_buffer[4]; - mke.vol1 = mke.command_buffer[6]; - mke.patch0 = mke.command_buffer[3]; - mke.patch1 = mke.command_buffer[5]; + memcpy(mke->mode_select, &mke->command_buffer[2], 5); + break; + case 5: + mke->vol0 = mke->command_buffer[4]; + mke->vol1 = mke->command_buffer[6]; + mke->patch0 = mke->command_buffer[3]; + mke->patch1 = mke->command_buffer[5]; break; - } } - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; - case CMD1_GETMODE: // 6 + case CMD1_GETMODE: + /* 6 */ mke_log("GET MODE\n"); - if (mke.command_buffer[1] == 5) { - uint8_t volsettings[5] = { 0, mke.patch0, mke.vol0, mke.patch1, mke.vol1 }; - fifo8_push_all(&mke.info_fifo, volsettings, 5); - } - else - fifo8_push_all(&mke.info_fifo, mke.mode_select, 5); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + if (mke->command_buffer[1] == 5) { + uint8_t volsettings[5] = { 0, mke->patch0, mke->vol0, mke->patch1, mke->vol1 }; + fifo8_push_all(&mke->info_fifo, volsettings, 5); + } else + fifo8_push_all(&mke->info_fifo, mke->mode_select, 5); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_PAUSERESUME: CHECK_READY(); - cdrom_audio_pause_resume(mke.cdrom_dev, mke.command_buffer[1] >> 7); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + cdrom_audio_pause_resume(mke->cdrom_dev, mke->command_buffer[1] >> 7); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; - case CMD1_CAPACITY: // 6 + case CMD1_CAPACITY: + /* 6 */ mke_log("DISK CAPACITY\n"); CHECK_READY(); - mke_disc_capacity(mke.cdrom_dev, (uint8_t *) &x); - // fifo8_push_all(&cdrom.info_fifo, x, 5); - fifo8_push_all(&mke.info_fifo, x, 5); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + mke_disc_capacity(mke->cdrom_dev, (uint8_t *) &x); + fifo8_push_all(&mke->info_fifo, x, 5); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; - case CMD1_DISKINFO: // 7 + case CMD1_DISKINFO: + /* 7 */ mke_log("DISK INFO\n"); CHECK_READY(); - mke_disc_info(mke.cdrom_dev, (uint8_t *) &x); - fifo8_push_all(&mke.info_fifo, x, 6); -#if 0 - for (i=0; i<6; i++) { - mke_log("%02x ",x[i]); - cdrom_fifo_write(&cdrom.info_fifo,x[i]); - } - mke_log("\n"); -#endif - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + mke_disc_info(mke->cdrom_dev, (uint8_t *) &x); + fifo8_push_all(&mke->info_fifo, x, 6); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_READTOC: CHECK_READY(); - fifo8_reset(&mke.info_fifo); -#if 0 - mke_log("READ TOC:"); - for (i=0; i<6; i++) { - mke_log("%02x ",mke.command_buffer[i+1]); - } - mke_log(" | "); -#endif - mke_read_toc(mke.cdrom_dev, (uint8_t *) &x, mke.command_buffer[2]); - fifo8_push_all(&mke.info_fifo, x, 8); -#if 0 - for (i=0; i<8; i++) { - mke_log("%02x ",x[i]); - cdrom_fifo_write(&cdrom.info_fifo,x[i]); - } - mke_log("\n"); -#endif - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_reset(&mke->info_fifo); + mke_read_toc(mke->cdrom_dev, (uint8_t *) &x, mke->command_buffer[2]); + fifo8_push_all(&mke->info_fifo, x, 8); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_PLAY_TI: - { CHECK_READY(); /* Index is ignored for now. */ - fifo8_reset(&mke.info_fifo); - if (!cdrom_audio_play(mke.cdrom_dev, mke.command_buffer[1], mke.command_buffer[3], 2)) { - fifo8_push(&mke.errors_fifo, 0x0E); - fifo8_push(&mke.errors_fifo, 0x10); - } else { - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_reset(&mke->info_fifo); + if (cdrom_audio_play(mke->cdrom_dev, mke->command_buffer[1], mke->command_buffer[3], 2)) + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + else { + fifo8_push(&mke->errors_fifo, 0x0E); + fifo8_push(&mke->errors_fifo, 0x10); } break; - } case CMD1_PLAY_MSF: CHECK_READY(); - fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke->info_fifo); mke_log("PLAY MSF:"); for (i = 0; i < 6; i++) { - mke_log("%02x ", mke.command_buffer[i + 1]); + mke_log("%02x ", mke->command_buffer[i + 1]); } mke_log("\n"); -#if 0 - cdrom_audio_playmsf(&cdrom, - mke.command_buffer[1], - mke.command_buffer[2], - mke.command_buffer[3], - mke.command_buffer[4], - mke.command_buffer[5], - mke.command_buffer[6] - ); -#endif { int msf = 1; - int pos = (mke.command_buffer[1] << 16) | (mke.command_buffer[2] << 8) | mke.command_buffer[3]; - int len = (mke.command_buffer[4] << 16) | (mke.command_buffer[5] << 8) | mke.command_buffer[6]; - if (!cdrom_audio_play(mke.cdrom_dev, pos, len, msf)) { - fifo8_push(&mke.errors_fifo, 0x0E); - fifo8_push(&mke.errors_fifo, 0x10); - } else { - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - } + int pos = (mke->command_buffer[1] << 16) | (mke->command_buffer[2] << 8) | + mke->command_buffer[3]; + int len = (mke->command_buffer[4] << 16) | (mke->command_buffer[5] << 8) | + mke->command_buffer[6]; + if (!cdrom_audio_play(mke->cdrom_dev, pos, len, msf)) { + fifo8_push(&mke->errors_fifo, 0x0E); + fifo8_push(&mke->errors_fifo, 0x10); + } else + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); } break; case CMD1_SEEK: CHECK_READY(); - old_cd_status = mke.cdrom_dev->cd_status; - fifo8_reset(&mke.info_fifo); - mke_log("SEEK MSF:"); // TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? + old_cd_status = mke->cdrom_dev->cd_status; + fifo8_reset(&mke->info_fifo); + /* TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? */ + mke_log("SEEK MSF:"); for (i = 0; i < 6; i++) { - mke_log("%02x ", mke.command_buffer[i + 1]); + mke_log("%02x ", mke->command_buffer[i + 1]); } - cdrom_stop(mke.cdrom_dev); + cdrom_stop(mke->cdrom_dev); /* Note for self: Panasonic/MKE drives send seek commands in MSF format. */ - cdrom_seek(mke.cdrom_dev, MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150, 0); - if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) { - cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, -1, 0); - cdrom_audio_pause_resume(mke.cdrom_dev, old_cd_status == CD_STATUS_PLAYING); + cdrom_seek(mke->cdrom_dev, MSFtoLBA(mke->command_buffer[1], mke->command_buffer[2], + mke->command_buffer[3]) - 150, 0); + if ((old_cd_status == CD_STATUS_PLAYING) || (old_cd_status == CD_STATUS_PAUSED)) { + cdrom_audio_play(mke->cdrom_dev, mke->cdrom_dev->seek_pos, -1, 0); + cdrom_audio_pause_resume(mke->cdrom_dev, old_cd_status == CD_STATUS_PLAYING); } - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_SESSINFO: CHECK_READY(); - fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke->info_fifo); mke_log("CMD: READ SESSION INFO\n"); - mke_read_multisess(); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + mke_read_multisess(mke); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_READ_UPC: CHECK_READY(); - fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke->info_fifo); mke_log("CMD: READ UPC\n"); uint8_t upc[8] = { [0] = 80 }; - fifo8_push_all(&mke.info_fifo, upc, 8); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_push_all(&mke->info_fifo, upc, 8); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_READ_ERR: - fifo8_reset(&mke.info_fifo); + fifo8_reset(&mke->info_fifo); mke_log("CMD: READ ERR\n"); - // cdrom_read_errors(&cdrom,(uint8_t *)x); memset(x, 0, 8); - if (fifo8_num_used(&mke.errors_fifo)) { - fifo8_pop_buf(&mke.errors_fifo, x, fifo8_num_used(&mke.errors_fifo)); - } - fifo8_push_all(&mke.info_fifo, x, 8); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); - fifo8_reset(&mke.errors_fifo); + if (fifo8_num_used(&mke->errors_fifo)) + fifo8_pop_buf(&mke->errors_fifo, x, fifo8_num_used(&mke->errors_fifo)); + fifo8_push_all(&mke->info_fifo, x, 8); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + fifo8_reset(&mke->errors_fifo); break; case CMD1_READ_VER: - /* - SB2CD Expects 12 bytes, but drive only returns 11. - */ - fifo8_reset(&mke.info_fifo); - // pclog("CMD: READ VER\n"); - fifo8_push_all(&mke.info_fifo, ver, 10); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + /* SB2CD Expects 12 bytes, but drive only returns 11. */ + fifo8_reset(&mke->info_fifo); + fifo8_push_all(&mke->info_fifo, ver, 10); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_STATUS: - fifo8_reset(&mke.info_fifo); - fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); + fifo8_reset(&mke->info_fifo); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; default: - mke_log("MKE: Unknown Commnad [%02x]\n", mke.command_buffer[0]); + mke_log("MKE: Unknown Commnad [%02x]\n", mke->command_buffer[0]); + break; } - } else if (!mke.command_buffer_pending) { // we are done byt not in a command. should we make sure it is a valid command here? - mke.command_buffer[0] = value; - mke.command_buffer_pending = 6; + } else if (!mke->command_buffer_pending) { + /* + We are done but not in a command. + Should we make sure it is a valid command here? + */ + mke->command_buffer[0] = value; + mke->command_buffer_pending = 6; } } void mke_write(uint16_t address, uint8_t value, void *priv) { - //pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value); - if (mke.enable_register && ((address & 0xF) != 3)) { - // mke_log("Ignore Write Unit %u\n",mke.enable_register); - return; - } - // mke_log("MKE WRITE: %02x => %03x\n",value,address); - switch (address & 0xF) { + mke_t *mke = (mke_t *) priv; + + if (!mke->enable_register || ((address & 0xf) == 3)) switch (address & 0xf) { case 0: - mke_command(value); + mke_command(mke, value); break; case 1: - mke.data_select = value; + if (mke->is_sb) + mke->data_select = value; break; case 2: - mke_reset(); + mke_reset(mke); break; case 3: - mke.enable_register = value; + mke->enable_register = value; break; default: - pclog("w %03x %02x\n", address, value); + mke_log("w %03x %02x\n", address, value); break; } } @@ -688,51 +667,50 @@ mke_write(uint16_t address, uint8_t value, void *priv) uint8_t mke_read(uint16_t address, void *priv) { - uint8_t x; - if (mke.enable_register) { - // pclog("Ignore Read Unit %u\n",mke.enable_register); - return 0; - } - // pclog("MKEREAD: 0x%X\n", address & 0xf); - switch (address & 0xF) { - case 0: // Info - if (mke.data_select) { - x = fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; // cdrom_fifo_read(&cdrom.data_fifo); - } else { - x = fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.info_fifo) : 0; - // return cdrom_fifo_read(&cdrom.info_fifo); - } - // pclog("Read FIFO 0x%X, %d\n", x, mke.data_select); - return x; + mke_t *mke = (mke_t *) priv; + uint8_t ret = 0x00; + + if (!mke->enable_register) switch (address & 0xf) { + case 0: + /* Info */ + if (mke->is_sb && mke->data_select) + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0; + else + ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0; break; - case 1: // Status + case 1: /* - 1 = Status Change - 2 = Data Ready - 4 = Response Ready - 8 = Attention / Issue ? + Status: + - 1 = Status Change; + - 2 = Data Ready; + - 4 = Response Ready; + - 8 = Attention / Issue? */ - x = 0xFF; - // if(cdrom.media_changed) x ^= 1; - if (fifo8_num_used(&mke.data_fifo)) - x ^= 2; // DATA FIFO - if (fifo8_num_used(&mke.info_fifo)) - x ^= 4; // STATUS FIFO - if (fifo8_num_used(&mke.errors_fifo)) - x ^= 8; - return x; + ret = 0xff; + if (fifo8_num_used(&mke->data_fifo)) + /* Data FIFO */ + ret ^= 2; + if (fifo8_num_used(&mke->info_fifo)) + /* Status FIFO */ + ret ^= 4; + if (fifo8_num_used(&mke->errors_fifo)) + ret ^= 8; + break; + case 2: + /* Data */ + if (!mke->is_sb) + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0; break; - case 2: // Data - return fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0; case 3: - return mke.enable_register; + ret = mke->enable_register; break; default: - /* mke_log("MKE Unknown Read Address: %03x\n",address); */ - pclog("MKE Unknown Read Address: %03x\n", address); + mke_log("MKE Unknown Read Address: %03x\n",address); + ret = 0xff; break; } - return 0xff; + + return ret; } void @@ -753,16 +731,14 @@ mke_cdrom_insert(void *priv) return; if (dev->cdrom_dev->ops == NULL) { - // dev->unit_attention = 0; dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; if (timer_is_enabled(&dev->timer)) { timer_disable(&dev->timer); - mke.data_to_push = 0; + dev->data_to_push = 0; fifo8_push(&dev->errors_fifo, 0x15); } fifo8_push(&dev->errors_fifo, 0x11); } else { - // dev->unit_attention = 1; /* Turn off the medium changed status. */ dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION; fifo8_push(&dev->errors_fifo, 0x11); @@ -772,20 +748,24 @@ mke_cdrom_insert(void *priv) uint32_t mke_get_volume(void *priv, int channel) { - return channel == 0 ? mke.vol0 : mke.vol1; + mke_t *dev = (mke_t *) priv; + + return channel == 0 ? dev->vol0 : dev->vol1; } uint32_t mke_get_channel(void *priv, int channel) { - return channel == 0 ? mke.patch0 : mke.patch1; + mke_t *dev = (mke_t *) priv; + + return channel == 0 ? dev->patch0 : dev->patch1; } void * mke_init(const device_t *info) { + mke_t *mke = (mke_t *) calloc(1, sizeof(mke_t)); cdrom_t *dev = NULL; - memset(&mke, 0, sizeof(mke_t)); for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type == CDROM_BUS_MKE) { @@ -797,33 +777,34 @@ mke_init(const device_t *info) if (!dev) return NULL; - fifo8_create(&mke.info_fifo, 128); - fifo8_create(&mke.data_fifo, 624240 * 2); - fifo8_create(&mke.errors_fifo, 8); - fifo8_reset(&mke.info_fifo); - fifo8_reset(&mke.data_fifo); - fifo8_reset(&mke.errors_fifo); - mke.cdrom_dev = dev; - mke.command_buffer_pending = 7; - mke.sector_type = 0x08 | (1 << 4); - mke.sector_flags = 0x10; - mke.mode_select[2] = 0x08; - mke.patch0 = 0x01; - mke.patch1 = 0x02; - mke.vol0 = 255; - mke.vol1 = 255; - dev->sector_size = 2048; + fifo8_create(&mke->info_fifo, 128); + fifo8_create(&mke->data_fifo, 624240 * 2); + fifo8_create(&mke->errors_fifo, 8); + fifo8_reset(&mke->info_fifo); + fifo8_reset(&mke->data_fifo); + fifo8_reset(&mke->errors_fifo); + mke->cdrom_dev = dev; + mke->command_buffer_pending = 7; + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->mode_select[2] = 0x08; + mke->patch0 = 0x01; + mke->patch1 = 0x02; + mke->vol0 = 255; + mke->vol1 = 255; + mke->is_sb = info->local; + dev->sector_size = 2048; - dev->priv = &mke; + dev->priv = mke; dev->insert = mke_cdrom_insert; dev->get_volume = mke_get_volume; dev->get_channel = mke_get_channel; dev->cached_sector = -1; - timer_add(&mke.timer, mke_command_callback, &mke, 0); + timer_add(&mke->timer, mke_command_callback, mke, 0); uint16_t base = device_get_config_hex16("base"); - io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); - return &mke; + io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, mke); + return mke; } static const device_config_t mke_config[] = { @@ -854,7 +835,7 @@ const device_t mke_cdrom_device = { .name = "Panasonic/MKE CD-ROM interface (Creative)", .internal_name = "mkecd", .flags = DEVICE_ISA16, - .local = 0, + .local = 1, .init = mke_init, .close = mke_close, .reset = NULL, From c6870e9248ed27227ea1b440438ad5073d6aca70 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 18:45:42 +0200 Subject: [PATCH 27/32] (S)VGA: Fix regression. --- src/video/vid_svga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0720910d6..3e20efb05 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1535,7 +1535,7 @@ svga_poll(void *priv) svga->scanline = (svga->crtc[0x8] & 0x1f); svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - } else { + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 1) From 1b142299e5b56daf860df163f10328138832246d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 19:03:34 +0200 Subject: [PATCH 28/32] Settings: Remove an excess logging line. --- src/qt/qt_settingsinput.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 6296cd1e9..0a6e99c62 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -127,7 +127,6 @@ SettingsInput::onCurrentMachineChanged(int machineId) continue; QString name = DeviceConfig::DeviceName(dev, keyboard_get_internal_name(i), 0); - pclog("Found valid keyboard: %s\n", name.toUtf8().data()); int row = keyboardModel->rowCount(); keyboardModel->insertRow(row); auto idx = keyboardModel->index(row, 0); From 26249b9c4ce15eca44cea8d5ea127d103c662d8a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 19:21:24 +0200 Subject: [PATCH 29/32] MKE: More clean-ups, made port 3 return 0xFF when read (fixes Windows 95's built-in Panasonic driver), and added the Non-Creative version as well. --- src/cdrom/cdrom.c | 9 +++++---- src/cdrom/cdrom_mke.c | 35 ++++++++++++++++++++--------------- src/include/86box/cdrom_mke.h | 1 + 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 7e1791771..0b9aa85d3 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -120,12 +120,13 @@ static const struct { const device_t *device; } controllers[] = { // clang-format off - { &cdrom_interface_none_device }, + { &cdrom_interface_none_device }, #ifdef USE_CDROM_MITSUMI - { &mitsumi_cdrom_device }, + { &mitsumi_cdrom_device }, #endif - { &mke_cdrom_device }, - { NULL } + { &mke_cdrom_noncreative_device }, + { &mke_cdrom_device }, + { NULL } // clang-format on }; diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index f2a4e1a6e..f92ff2dbc 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -38,6 +38,9 @@ #include <86box/sound.h> #include <86box/fifo8.h> #include <86box/timer.h> +#ifdef ENABLE_MKE_LOG +#include "cpu.h" +#endif /* https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h @@ -168,7 +171,8 @@ mke_get_subq(cdrom_t *dev, uint8_t *b) b[9] = temp_buf[5]; /* ? */ b[10] = 0; - pclog("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); + mke_log("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); } /* Lifted from FreeBSD */ @@ -640,23 +644,25 @@ mke_command(mke_t *mke, uint8_t value) } void -mke_write(uint16_t address, uint8_t value, void *priv) +mke_write(uint16_t port, uint8_t val, void *priv) { mke_t *mke = (mke_t *) priv; - if (!mke->enable_register || ((address & 0xf) == 3)) switch (address & 0xf) { + mke_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + + if (!mke->enable_register || ((port & 0xf) == 3)) switch (port & 0xf) { case 0: - mke_command(mke, value); + mke_command(mke, val); break; case 1: if (mke->is_sb) - mke->data_select = value; + mke->data_select = val; break; case 2: mke_reset(mke); break; case 3: - mke->enable_register = value; + mke->enable_register = val; break; default: mke_log("w %03x %02x\n", address, value); @@ -665,18 +671,18 @@ mke_write(uint16_t address, uint8_t value, void *priv) } uint8_t -mke_read(uint16_t address, void *priv) +mke_read(uint16_t port, void *priv) { mke_t *mke = (mke_t *) priv; uint8_t ret = 0x00; - if (!mke->enable_register) switch (address & 0xf) { + if (!mke->enable_register) switch (port & 0xf) { case 0: /* Info */ if (mke->is_sb && mke->data_select) - ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0; + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00; else - ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0; + ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0x00; break; case 1: /* @@ -699,17 +705,16 @@ mke_read(uint16_t address, void *priv) case 2: /* Data */ if (!mke->is_sb) - ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0; - break; - case 3: - ret = mke->enable_register; + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00; break; default: - mke_log("MKE Unknown Read Address: %03x\n",address); + mke_log("MKE Unknown Read Port: %04X\n", port); ret = 0xff; break; } + mke_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + return ret; } diff --git a/src/include/86box/cdrom_mke.h b/src/include/86box/cdrom_mke.h index 3c946246c..659e084e3 100644 --- a/src/include/86box/cdrom_mke.h +++ b/src/include/86box/cdrom_mke.h @@ -19,5 +19,6 @@ #define CDROM_MKE_H extern const device_t mke_cdrom_device; +extern const device_t mke_cdrom_noncreative_device; #endif /*CDROM_MKE_H*/ From 84464dfe41526c8cc84c00a22c26f64c845c67e3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 27 Jul 2025 19:57:45 +0200 Subject: [PATCH 30/32] AMD 53c974 changes and fixes (July 27th, 2025) 1. Implemented as best as possible the MDL S/G required by NeXTSTEP/OPENSTEP, fixes detection of storage devices. 2. Timer bits from the Clock registers are now implemented. --- src/scsi/scsi_pcscsi.c | 117 +++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 39 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 1b1f6113d..4f8015b07 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -46,6 +46,7 @@ #include <86box/scsi_pcscsi.h> #include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> +#include "cpu.h" #define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" #define AM53C974_ROM "roms/scsi/esp_pci/harom.bin" @@ -632,7 +633,10 @@ esp_dma_enable(esp_t *dev, int level) dev->dma_enabled = 1; timer_stop(&dev->timer); if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { - timer_on_auto(&dev->timer, 40.0); + if (dev->wregs[ESP_WCCF] & 0x07) + timer_on_auto(&dev->timer, ((double)(dev->wregs[ESP_WCCF] & 0x07)) * 5.0); + else + timer_on_auto(&dev->timer, 40.0); } else { esp_log("Period = %lf\n", dev->period); timer_on_auto(&dev->timer, dev->period); @@ -702,13 +706,14 @@ esp_do_dma(esp_t *dev) uint8_t buf[ESP_CMDFIFO_SZ]; uint32_t len; - esp_log("ESP SCSI Actual DMA len = %d\n", esp_get_tc(dev)); - len = esp_get_tc(dev); + esp_log("ESP SCSI Actual DMA len=%d, cfg3=%02x.\n", len, dev->rregs[ESP_CFG3]); + switch (esp_get_phase(dev)) { case STAT_MO: len = MIN(len, fifo8_num_free(&dev->cmdfifo)); + esp_log("ESP SCSI Message Out len=%d.\n", len); if (len) { if (dev->mca) { dma_set_drq(dev->DmaChannel, 1); @@ -1030,6 +1035,7 @@ esp_do_nodma(esp_t *dev) /* Copy FIFO into cmdfifo */ len = esp_fifo_pop_buf(dev, buf, fifo8_num_used(&dev->fifo)); len = MIN(fifo8_num_free(&dev->cmdfifo), len); + esp_log("ESP Message Out CMD SelAtn len=%d.\n", len); fifo8_push_all(&dev->cmdfifo, buf, len); if (fifo8_num_used(&dev->cmdfifo) >= 1) { @@ -1243,15 +1249,18 @@ esp_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if (dev->mca) { - /* Normal SCSI: 5000000 bytes per second */ - dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); - } else { + if ((dev->rregs[ESP_CFG3] & 0x18) == 0x18) { /* Fast SCSI: 10000000 bytes per second */ dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + } else { + /* Normal SCSI: 5000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); } - timer_on_auto(&dev->timer, dev->period + 40.0); + if ((dev->wregs[ESP_WCCF] & 0x07) == 0x00) + timer_on_auto(&dev->timer, dev->period + 40.0); + else + timer_on_auto(&dev->timer, dev->period + (((double)(dev->wregs[ESP_WCCF] & 0x07)) * 5.0)); } static void @@ -1407,9 +1416,9 @@ esp_reg_read(esp_t *dev, uint32_t saddr) esp_log("ESP RINTR read old val = %02x\n", ret); break; case ESP_TCHI: /* Return the unique id if the value has never been written */ - if (dev->mca) { + if (dev->mca) ret = dev->rregs[ESP_TCHI]; - } else { + else { if (!dev->tchi_written) ret = TCHI_AM53C974; else @@ -1437,7 +1446,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) fallthrough; case ESP_TCLO: case ESP_TCMID: - esp_log("ESP TCW reg%02x = %02x.\n", saddr, val); + esp_log("%04X:%08X: ESP TCW reg%02x = %02x.\n", CS, cpu_state.pc, saddr, val); dev->rregs[ESP_RSTAT] &= ~STAT_TC; break; case ESP_FIFO: @@ -1448,7 +1457,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case ESP_CMD: dev->rregs[ESP_CMD] = val; - if (!esp_cmd_is_valid(dev, dev->rregs[saddr])) { + if (!esp_cmd_is_valid(dev, dev->rregs[ESP_CMD])) { dev->rregs[ESP_RSTAT] |= INTR_IL; esp_raise_irq(dev); break; @@ -1460,9 +1469,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_set_tc(dev, esp_get_stc(dev)); if (!esp_get_stc(dev)) { if (dev->rregs[ESP_CFG2] & 0x40) - esp_set_tc(dev, 0x1000000); + esp_set_tc(dev, 0x1000000 - 1); else - esp_set_tc(dev, 0x10000); + esp_set_tc(dev, 0x10000 - 1); } } else { dev->dma = 0; @@ -1532,7 +1541,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_ENSEL: dev->rregs[ESP_RINTR] = 0; - esp_log("ESP Enable Selection, do cmd = %d\n", dev->do_cmd); + esp_log("ESP Enable Selection.\n"); break; case CMD_DISSEL: dev->rregs[ESP_RINTR] = 0; @@ -1571,9 +1580,12 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) static void esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) { - uint32_t sg_pos = 0; uint32_t addr; int expected_dir; + int sg_pos = 0; + uint32_t DMALen; + uint32_t DMAPtr; + uint32_t WAC = 0; if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) expected_dir = READ_FROM_DEVICE; @@ -1586,34 +1598,58 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) } if (dev->dma_regs[DMA_CMD] & DMA_CMD_MDL) { - if (dev->dma_regs[DMA_STC]) { - if (dev->dma_regs[DMA_WBC] > len) - dev->dma_regs[DMA_WBC] = len; + if (dev->dma_regs[DMA_WBC] < len) + len = dev->dma_regs[DMA_WBC]; + + if (len) { + dma_bm_read(dev->dma_regs[DMA_WMAC], (uint8_t *)&DMAPtr, 4, 4); + dev->dma_regs[DMA_WAC] = DMAPtr | dev->dma_regs[DMA_SPA]; + DMALen = len; + WAC = dev->dma_regs[DMA_SPA]; + for (uint32_t i = 0; i < len; i += 4) { + if (WAC == 0) { + dma_bm_read(dev->dma_regs[DMA_WMAC], (uint8_t *)&DMAPtr, 4, 4); + dev->dma_regs[DMA_WAC] = DMAPtr; + } - esp_log("WAC MDL=%08x, STC=%d, ID=%d.\n", dev->dma_regs[DMA_WAC] | (dev->dma_regs[DMA_WMAC] & 0xff000), dev->dma_regs[DMA_STC], dev->id); - for (uint32_t i = 0; i < len; i++) { addr = dev->dma_regs[DMA_WAC]; - if (expected_dir) - dma_bm_write(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4); - else - dma_bm_read(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4); + esp_log("Data Buffer %s: length %d (%u), pointer 0x%04X\n", + expected_dir ? "read" : "write", len, len, addr); - sg_pos++; - dev->dma_regs[DMA_WBC]--; - dev->dma_regs[DMA_WAC]++; - - if (dev->dma_regs[DMA_WAC] & 0x1000) { - dev->dma_regs[DMA_WAC] = 0; - dev->dma_regs[DMA_WMAC] += 0x1000; + if (addr && DMALen) { + if (expected_dir) + dma_bm_write(addr, &buf[sg_pos], DMALen, 4); + else + dma_bm_read(addr, &buf[sg_pos], DMALen, 4); } + sg_pos += 4; + DMALen -= 4; + + /* update status registers */ + dev->dma_regs[DMA_WBC] -= 4; + dev->dma_regs[DMA_WAC] += 4; + WAC += 4; + if (WAC >= 0x1000) { + WAC = 0; + dev->dma_regs[DMA_WMAC] += 4; + } + + if (DMALen < 0) + DMALen = 0; + if (dev->dma_regs[DMA_WBC] <= 0) { dev->dma_regs[DMA_WBC] = 0; - dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + break; } } } + esp_log("Finished count=%d.\n", dev->dma_regs[DMA_WBC]); + if (dev->dma_regs[DMA_WBC] == 0) { + esp_log("DMA transfer finished.\n"); + dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + } } else { if (dev->dma_regs[DMA_WBC] < len) len = dev->dma_regs[DMA_WBC]; @@ -1629,8 +1665,11 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) dev->dma_regs[DMA_WBC] -= len; dev->dma_regs[DMA_WAC] += len; - if (dev->dma_regs[DMA_WBC] == 0) + esp_log("Finished count=%d.\n", dev->dma_regs[DMA_WBC]); + if (dev->dma_regs[DMA_WBC] == 0) { + esp_log("DMA transfer finished.\n"); dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + } } } @@ -1674,12 +1713,12 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]); break; case 3: /*START*/ + dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA]; - dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc; - if (!dev->dma_regs[DMA_STC]) - dev->dma_regs[DMA_STC] = 0x1000000; - dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; + if (val & DMA_CMD_MDL) + dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc; + dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN); esp_dma_enable(dev, 1); esp_log("PCI DMA enable, MDL bit=%02x, SPA=%08x, SMDLA=%08x, STC=%d, ID=%d, SCSICMD=%02x.\n", val & DMA_CMD_MDL, dev->dma_regs[DMA_SPA], dev->dma_regs[DMA_SMDLA], dev->dma_regs[DMA_STC], dev->id, dev->cmdfifo.data[1]); @@ -2505,7 +2544,7 @@ ncr53c9x_mca_init(const device_t *info) timer_add(&dev->timer, esp_callback, dev, 0); - scsi_bus_set_speed(dev->bus, 5000000.0); + scsi_bus_set_speed(dev->bus, 10000000.0); return dev; } From 9a1e09375f173829fea2cf77127a99b50b2b2640 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 22:23:21 +0200 Subject: [PATCH 31/32] MKE CD-ROM: Add ports 220h and 300h-340h, allows CR56X.SYS to work without the /P: parameter. --- src/cdrom/cdrom_mke.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index f92ff2dbc..3b2b7b128 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -665,7 +665,6 @@ mke_write(uint16_t port, uint8_t val, void *priv) mke->enable_register = val; break; default: - mke_log("w %03x %02x\n", address, value); break; } } @@ -823,11 +822,17 @@ static const device_config_t mke_config[] = { .file_filter = NULL, .spinner = { 0 }, .selection = { + { .description = "220H", .value = 0x220 }, { .description = "230H", .value = 0x230 }, { .description = "250H", .value = 0x250 }, { .description = "260H", .value = 0x260 }, { .description = "270H", .value = 0x270 }, { .description = "290H", .value = 0x290 }, + { .description = "300H", .value = 0x300 }, + { .description = "310H", .value = 0x310 }, + { .description = "320H", .value = 0x320 }, + { .description = "330H", .value = 0x330 }, + { .description = "340H", .value = 0x340 }, { NULL } }, .bios = { { 0 } } From f4d3924c8c785dc30252c0dbc3b48b91fd3aefd0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 27 Jul 2025 22:32:42 +0200 Subject: [PATCH 32/32] MKE CD-ROM: Remove useless code from get capacity, fixes random segfaults. --- src/cdrom/cdrom_mke.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 3b2b7b128..91765f8ab 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -239,17 +239,9 @@ mke_disc_info(cdrom_t *dev, unsigned char *b) uint8_t mke_disc_capacity(cdrom_t *dev, unsigned char *b) { - track_info_t ti; - int last_track; - - cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); - last_track = temp_buf[3]; - dev->ops->get_track_info(dev, last_track + 1, 0, &ti); - - b[0] = ti.m; - b[1] = ti.s; - /* TODO THIS NEEDS TO HANDLE FRAME 0, JUST BEING LAZY 6AM */ - b[2] = ti.f - 1; + b[0] = 0x00; + b[1] = 0x00; + b[2] = 0x00; b[3] = 0x08; b[4] = 0x00;