2025-07-25 17:23:42 -04:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2025-07-27 01:42:12 +06:00
|
|
|
* Panasonic/MKE CD-ROM emulation for the ISA bus.
|
2025-07-25 17:23:42 -04:00
|
|
|
*
|
|
|
|
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
2025-07-27 01:42:12 +06:00
|
|
|
* Kevin Moonlight, <me@yyzkevin.com>
|
2025-07-25 17:23:42 -04:00
|
|
|
* Cacodemon345
|
|
|
|
|
*
|
2025-07-27 01:42:12 +06:00
|
|
|
* Copyright (C) 2025 Miran Grca.
|
|
|
|
|
* Copyright (C) 2025 Cacodemon345.
|
|
|
|
|
* Copyright (C) 2024 Kevin Moonlight.
|
2025-07-25 17:23:42 -04:00
|
|
|
*/
|
2025-07-25 16:26:36 +06:00
|
|
|
#include <inttypes.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#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>
|
2025-07-27 02:17:55 +06:00
|
|
|
#include <86box/ui.h>
|
2025-07-25 16:26:36 +06:00
|
|
|
#include <86box/sound.h>
|
|
|
|
|
#include <86box/fifo8.h>
|
2025-07-27 02:17:55 +06:00
|
|
|
#include <86box/timer.h>
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h
|
2025-07-25 17:23:42 -04:00
|
|
|
CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix.
|
2025-07-25 16:26:36 +06:00
|
|
|
*/
|
|
|
|
|
#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
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
// 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
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
#define CMD1_PAUSERESUME 0x0D
|
2025-07-25 17:23:42 -04:00
|
|
|
#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
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
typedef struct mke_t {
|
2025-07-25 17:23:42 -04:00
|
|
|
bool tray_open;
|
|
|
|
|
|
2025-07-25 16:26:36 +06:00
|
|
|
uint8_t enable_register;
|
|
|
|
|
|
|
|
|
|
uint8_t command_buffer[7];
|
|
|
|
|
uint8_t command_buffer_pending;
|
|
|
|
|
|
2025-07-27 01:42:12 +06:00
|
|
|
uint8_t vol0, vol1, patch0, patch1;
|
|
|
|
|
uint8_t mode_select[5];
|
|
|
|
|
|
2025-07-25 16:26:36 +06:00
|
|
|
uint8_t data_select;
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t media_selected; // temporary hack
|
2025-07-25 16:26:36 +06:00
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
Fifo8 data_fifo;
|
|
|
|
|
Fifo8 info_fifo;
|
2025-07-25 16:26:36 +06:00
|
|
|
Fifo8 errors_fifo;
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
cdrom_t *cdrom_dev;
|
2025-07-25 16:26:36 +06:00
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint32_t sector_type;
|
|
|
|
|
uint32_t sector_flags;
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
uint32_t unit_attention;
|
|
|
|
|
|
2025-07-27 02:17:55 +06:00
|
|
|
uint8_t cdbuffer[624240 * 2];
|
|
|
|
|
|
|
|
|
|
uint32_t data_to_push;
|
|
|
|
|
|
|
|
|
|
pc_timer_t timer;
|
2025-07-25 16:26:36 +06:00
|
|
|
} mke_t;
|
|
|
|
|
mke_t mke;
|
|
|
|
|
|
|
|
|
|
#define mke_log(x, ...)
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
#define CHECK_READY() \
|
|
|
|
|
{ \
|
|
|
|
|
if (mke.cdrom_dev->cd_status == CD_STATUS_EMPTY) { \
|
|
|
|
|
fifo8_push(&mke.errors_fifo, 0x03); \
|
|
|
|
|
return; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
static uint8_t temp_buf[65536];
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
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
|
2025-07-26 23:22:51 +06:00
|
|
|
cdrom_get_current_subchannel_sony(dev, temp_buf, 1);
|
2025-07-25 17:23:42 -04:00
|
|
|
b[0] = 0x80; //?
|
2025-07-26 23:22:51 +06:00
|
|
|
b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4);
|
2025-07-25 17:23:42 -04:00
|
|
|
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; //??
|
2025-07-26 17:19:56 +06:00
|
|
|
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]);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
2025-07-26 17:19:56 +06:00
|
|
|
// Lifted from FreeBSD
|
|
|
|
|
|
|
|
|
|
static void blk_to_msf(int blk, unsigned char *msf)
|
2025-07-25 17:23:42 -04:00
|
|
|
{
|
2025-07-26 17:19:56 +06:00
|
|
|
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) {
|
2025-07-25 16:26:36 +06:00
|
|
|
track_info_t ti;
|
2025-07-26 17:19:56 +06:00
|
|
|
int last_track;
|
2025-07-25 16:26:36 +06:00
|
|
|
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536);
|
2025-07-26 17:19:56 +06:00
|
|
|
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;
|
2025-07-25 17:23:42 -04:00
|
|
|
}
|
|
|
|
|
|
2025-07-26 17:19:56 +06:00
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t
|
|
|
|
|
mke_disc_info(cdrom_t *dev, unsigned char *b)
|
|
|
|
|
{
|
2025-07-27 02:38:46 +06:00
|
|
|
uint8_t disc_type_buf[34];
|
2025-07-25 17:23:42 -04:00
|
|
|
int first_track;
|
|
|
|
|
int last_track;
|
2025-07-26 17:19:56 +06:00
|
|
|
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536);
|
2025-07-27 02:38:46 +06:00
|
|
|
cdrom_read_disc_information(dev, disc_type_buf);
|
2025-07-25 16:26:36 +06:00
|
|
|
first_track = temp_buf[2];
|
2025-07-25 17:23:42 -04:00
|
|
|
last_track = temp_buf[3];
|
2025-07-26 17:19:56 +06:00
|
|
|
// dev->ops->get_track_info(dev, last_track + 1, 0, &ti);
|
2025-07-27 02:38:46 +06:00
|
|
|
b[0] = disc_type_buf[8];
|
2025-07-25 17:23:42 -04:00
|
|
|
b[1] = first_track;
|
|
|
|
|
b[2] = last_track;
|
2025-07-26 17:19:56 +06:00
|
|
|
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]);
|
2025-07-25 17:23:42 -04:00
|
|
|
return 1;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t
|
|
|
|
|
mke_disc_capacity(cdrom_t *dev, unsigned char *b)
|
|
|
|
|
{
|
2025-07-25 16:26:36 +06:00
|
|
|
track_info_t ti;
|
2025-07-25 17:23:42 -04:00
|
|
|
int last_track;
|
|
|
|
|
// dev->ops->get_tracks(dev, &first_track, &last_track);
|
2025-07-26 17:19:56 +06:00
|
|
|
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536);
|
2025-07-25 17:23:42 -04:00
|
|
|
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;
|
2025-07-26 17:19:56 +06:00
|
|
|
|
|
|
|
|
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]);
|
2025-07-25 17:23:42 -04:00
|
|
|
return 1;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t
|
|
|
|
|
mke_cdrom_status(cdrom_t *dev, mke_t *mke)
|
|
|
|
|
{
|
2025-07-26 00:32:21 +06:00
|
|
|
uint8_t status = 0;
|
2025-07-25 17:23:42 -04:00
|
|
|
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?
|
2025-07-25 16:26:36 +06:00
|
|
|
status |= STAT_TRAY;
|
2025-07-26 00:32:21 +06:00
|
|
|
if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) {
|
|
|
|
|
status |= STAT_DISK;
|
2025-07-25 16:26:36 +06:00
|
|
|
status |= STAT_READY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-27 12:55:10 +06:00
|
|
|
void
|
|
|
|
|
mke_read_multisess(void)
|
|
|
|
|
{
|
|
|
|
|
int len = cdrom_read_toc(mke.cdrom_dev, temp_buf, CD_TOC_SESSION, 0, 1, 65536);
|
2025-07-27 14:31:13 +06:00
|
|
|
if (temp_buf[9] != 0 || temp_buf[10] != 0 || temp_buf[11] != 0) {
|
2025-07-27 12:55:10 +06:00
|
|
|
/* 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]);
|
2025-07-27 14:31:13 +06:00
|
|
|
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);
|
2025-07-27 12:55:10 +06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-26 00:32:21 +06:00
|
|
|
uint8_t ver[10] = "CR-5630.75";
|
2025-07-25 17:23:42 -04:00
|
|
|
|
2025-07-27 01:42:12 +06:00
|
|
|
static void
|
|
|
|
|
mke_reset(void)
|
|
|
|
|
{
|
|
|
|
|
cdrom_stop(mke.cdrom_dev);
|
2025-07-27 02:17:55 +06:00
|
|
|
timer_disable(&mke.timer);
|
2025-07-27 01:42:12 +06:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-27 02:17:55 +06:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
void
|
|
|
|
|
mke_command(uint8_t value)
|
|
|
|
|
{
|
2025-07-27 12:12:44 +06:00
|
|
|
uint16_t i;
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t x[12]; // this is wasteful handling of buffers for compatibility, but will optimize later.
|
|
|
|
|
int old_cd_status;
|
2025-07-25 16:26:36 +06:00
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
if (mke.command_buffer_pending) {
|
|
|
|
|
mke.command_buffer[6 - mke.command_buffer_pending + 1] = value;
|
|
|
|
|
mke.command_buffer_pending--;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
if (mke.command_buffer[0] == CMD1_ABORT) {
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("CMD_ABORT\n");
|
2025-07-25 17:23:42 -04:00
|
|
|
// fifo8_reset(&mke.info_fifo);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-27 02:17:55 +06:00
|
|
|
fifo8_reset(&mke.data_fifo);
|
|
|
|
|
timer_disable(&mke.timer);
|
2025-07-25 17:23:42 -04:00
|
|
|
mke.command_buffer[0] = 0;
|
|
|
|
|
mke.command_buffer_pending = 7;
|
|
|
|
|
// fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mke.command_buffer_pending && mke.command_buffer[0]) {
|
2025-07-25 17:23:42 -04:00
|
|
|
mke.command_buffer_pending = 7;
|
2025-07-26 17:19:56 +06:00
|
|
|
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]);
|
2025-07-25 16:26:36 +06:00
|
|
|
switch (mke.command_buffer[0]) {
|
2025-07-25 17:23:42 -04:00
|
|
|
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;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
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;
|
|
|
|
|
}
|
2025-07-27 01:42:12 +06:00
|
|
|
case CMD1_RESET:
|
|
|
|
|
{
|
|
|
|
|
mke_reset();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
case CMD1_READ:
|
|
|
|
|
{
|
|
|
|
|
uint32_t count = mke.command_buffer[6];
|
|
|
|
|
uint8_t *buf = mke.cdbuffer;
|
|
|
|
|
int res = 0;
|
2025-07-26 21:17:32 +06:00
|
|
|
uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150;
|
2025-07-27 12:12:44 +06:00
|
|
|
int len __attribute__((unused)) = 0;
|
2025-07-25 17:23:42 -04:00
|
|
|
CHECK_READY();
|
2025-07-27 02:17:55 +06:00
|
|
|
mke.data_to_push = 0;
|
2025-07-25 17:23:42 -04:00
|
|
|
while (count) {
|
|
|
|
|
if ((res = cdrom_readsector_raw(mke.cdrom_dev, buf, lba, 0, mke.sector_type, mke.sector_flags, &len, 0)) > 0) {
|
2025-07-27 02:17:55 +06:00
|
|
|
//fifo8_push_all(&mke.data_fifo, buf, mke.cdrom_dev->sector_size);
|
2025-07-25 17:23:42 -04:00
|
|
|
lba++;
|
|
|
|
|
buf += mke.cdrom_dev->sector_size;
|
2025-07-27 02:17:55 +06:00
|
|
|
mke.data_to_push += mke.cdrom_dev->sector_size;
|
2025-07-25 17:23:42 -04:00
|
|
|
} else {
|
|
|
|
|
fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
count--;
|
|
|
|
|
}
|
|
|
|
|
if (count != 0) {
|
|
|
|
|
fifo8_reset(&mke.data_fifo);
|
2025-07-27 02:17:55 +06:00
|
|
|
mke.data_to_push = 0;
|
2025-07-26 21:52:50 +06:00
|
|
|
} else {
|
2025-07-27 02:17:55 +06:00
|
|
|
//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);
|
2025-07-25 17:23:42 -04:00
|
|
|
}
|
|
|
|
|
break;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
case CMD1_READSUBQ:
|
|
|
|
|
CHECK_READY();
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_get_subq(mke.cdrom_dev, (uint8_t *) &x);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-25 17:23:42 -04:00
|
|
|
// fifo8_push_all(&cdrom.info_fifo, x, 11);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push_all(&mke.info_fifo, x, 11);
|
2025-07-25 17:23:42 -04:00
|
|
|
#if 0
|
|
|
|
|
for (i=0; i < 11; i++) {
|
|
|
|
|
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
#endif
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case CMD1_SETMODE: // Returns 1
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
|
|
|
|
mke_log("CMD: SET MODE:");
|
2025-07-25 17:23:42 -04:00
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
|
mke_log("%02x ", mke.command_buffer[i + 1]);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
mke_log("\n");
|
2025-07-27 01:42:12 +06:00
|
|
|
switch (mke.command_buffer[1]) {
|
|
|
|
|
case 0:
|
|
|
|
|
{
|
|
|
|
|
switch (mke.command_buffer[2]) {
|
2025-07-27 02:38:46 +06:00
|
|
|
case 0x00: /* Cooked */ {
|
2025-07-27 01:42:12 +06:00
|
|
|
mke.sector_type = 0x08 | (1 << 4);
|
|
|
|
|
mke.sector_flags = 0x10;
|
|
|
|
|
mke.cdrom_dev->sector_size = 2048;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-07-27 02:38:46 +06:00
|
|
|
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 */ {
|
2025-07-27 01:42:12 +06:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case CMD1_GETMODE: // 6
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("GET MODE\n");
|
2025-07-27 01:42:12 +06:00
|
|
|
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);
|
2025-07-25 16:26:36 +06:00
|
|
|
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;
|
2025-07-25 17:23:42 -04:00
|
|
|
case CMD1_CAPACITY: // 6
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("DISK CAPACITY\n");
|
|
|
|
|
CHECK_READY();
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_disc_capacity(mke.cdrom_dev, (uint8_t *) &x);
|
|
|
|
|
// fifo8_push_all(&cdrom.info_fifo, x, 5);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push_all(&mke.info_fifo, x, 5);
|
|
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case CMD1_DISKINFO: // 7
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("DISK INFO\n");
|
|
|
|
|
CHECK_READY();
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_disc_info(mke.cdrom_dev, (uint8_t *) &x);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push_all(&mke.info_fifo, x, 6);
|
2025-07-25 17:23:42 -04:00
|
|
|
#if 0
|
|
|
|
|
for (i=0; i<6; i++) {
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("%02x ",x[i]);
|
|
|
|
|
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
|
|
|
|
|
}
|
|
|
|
|
mke_log("\n");
|
2025-07-25 17:23:42 -04:00
|
|
|
#endif
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
|
|
|
|
case CMD1_READTOC:
|
|
|
|
|
CHECK_READY();
|
|
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-25 17:23:42 -04:00
|
|
|
#if 0
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("READ TOC:");
|
2025-07-25 17:23:42 -04:00
|
|
|
for (i=0; i<6; i++) {
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("%02x ",mke.command_buffer[i+1]);
|
|
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_log(" | ");
|
|
|
|
|
#endif
|
|
|
|
|
mke_read_toc(mke.cdrom_dev, (uint8_t *) &x, mke.command_buffer[2]);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push_all(&mke.info_fifo, x, 8);
|
2025-07-25 17:23:42 -04:00
|
|
|
#if 0
|
|
|
|
|
for (i=0; i<8; i++) {
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("%02x ",x[i]);
|
|
|
|
|
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
|
|
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_log("\n");
|
|
|
|
|
#endif
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
2025-07-27 12:55:10 +06:00
|
|
|
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;
|
|
|
|
|
}
|
2025-07-25 16:26:36 +06:00
|
|
|
case CMD1_PLAY_MSF:
|
|
|
|
|
CHECK_READY();
|
|
|
|
|
fifo8_reset(&mke.info_fifo);
|
|
|
|
|
mke_log("PLAY MSF:");
|
2025-07-25 17:23:42 -04:00
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
|
mke_log("%02x ", mke.command_buffer[i + 1]);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
mke_log("\n");
|
2025-07-25 17:23:42 -04:00
|
|
|
#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
|
2025-07-25 16:26:36 +06:00
|
|
|
{
|
|
|
|
|
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);
|
2025-07-26 22:41:22 +06:00
|
|
|
} else {
|
|
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case CMD1_SEEK:
|
|
|
|
|
CHECK_READY();
|
|
|
|
|
old_cd_status = mke.cdrom_dev->cd_status;
|
|
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-25 17:23:42 -04:00
|
|
|
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]);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
|
2025-07-25 16:26:36 +06:00
|
|
|
cdrom_stop(mke.cdrom_dev);
|
2025-07-26 22:41:22 +06:00
|
|
|
/* Note for self: Panasonic/MKE drives send seek commands in MSF format. */
|
2025-07-26 23:22:51 +06:00
|
|
|
cdrom_seek(mke.cdrom_dev, MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150, 0);
|
2025-07-25 16:26:36 +06:00
|
|
|
if (old_cd_status == CD_STATUS_PLAYING || old_cd_status == CD_STATUS_PAUSED) {
|
2025-07-26 23:22:51 +06:00
|
|
|
cdrom_audio_play(mke.cdrom_dev, mke.cdrom_dev->seek_pos, -1, 0);
|
2025-07-25 16:26:36 +06:00
|
|
|
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));
|
2025-07-25 17:23:42 -04:00
|
|
|
break;
|
2025-07-25 16:26:36 +06:00
|
|
|
case CMD1_SESSINFO:
|
|
|
|
|
CHECK_READY();
|
2025-07-25 17:23:42 -04:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-25 16:26:36 +06:00
|
|
|
mke_log("CMD: READ SESSION INFO\n");
|
2025-07-27 12:55:10 +06:00
|
|
|
mke_read_multisess();
|
2025-07-25 16:26:36 +06:00
|
|
|
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");
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t upc[8] = { [0] = 80 };
|
2025-07-25 16:26:36 +06:00
|
|
|
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:
|
2025-07-25 17:23:42 -04:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
|
|
|
|
mke_log("CMD: READ ERR\n");
|
|
|
|
|
// cdrom_read_errors(&cdrom,(uint8_t *)x);
|
2025-07-25 16:26:36 +06:00
|
|
|
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);
|
2025-07-25 17:23:42 -04:00
|
|
|
break;
|
2025-07-25 16:26:36 +06:00
|
|
|
case CMD1_READ_VER:
|
|
|
|
|
/*
|
|
|
|
|
SB2CD Expects 12 bytes, but drive only returns 11.
|
|
|
|
|
*/
|
|
|
|
|
fifo8_reset(&mke.info_fifo);
|
2025-07-25 17:23:42 -04:00
|
|
|
// pclog("CMD: READ VER\n");
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push_all(&mke.info_fifo, ver, 10);
|
|
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
|
|
|
|
break;
|
|
|
|
|
case CMD1_STATUS:
|
2025-07-25 17:23:42 -04:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
|
|
|
|
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
|
|
|
|
default:
|
2025-07-25 17:23:42 -04:00
|
|
|
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;
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
void
|
|
|
|
|
mke_write(uint16_t address, uint8_t value, void *priv)
|
|
|
|
|
{
|
2025-07-26 17:19:56 +06:00
|
|
|
//pclog("MKEWRITE: 0x%X, 0x%02X\n", address & 0xf, value);
|
2025-07-25 17:23:42 -04:00
|
|
|
if (mke.enable_register && ((address & 0xF) != 3)) {
|
|
|
|
|
// mke_log("Ignore Write Unit %u\n",mke.enable_register);
|
2025-07-25 16:26:36 +06:00
|
|
|
return;
|
|
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
// mke_log("MKE WRITE: %02x => %03x\n",value,address);
|
|
|
|
|
switch (address & 0xF) {
|
2025-07-25 16:26:36 +06:00
|
|
|
case 0:
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_command(value);
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case 1:
|
|
|
|
|
mke.data_select = value;
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
2025-07-27 01:42:12 +06:00
|
|
|
case 2:
|
|
|
|
|
mke_reset();
|
|
|
|
|
break;
|
2025-07-25 16:26:36 +06:00
|
|
|
case 3:
|
2025-07-25 17:23:42 -04:00
|
|
|
mke.enable_register = value;
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
pclog("w %03x %02x\n", address, value);
|
|
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
}
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
uint8_t
|
|
|
|
|
mke_read(uint16_t address, void *priv)
|
|
|
|
|
{
|
2025-07-25 16:26:36 +06:00
|
|
|
uint8_t x;
|
2025-07-25 17:23:42 -04:00
|
|
|
if (mke.enable_register) {
|
|
|
|
|
// pclog("Ignore Read Unit %u\n",mke.enable_register);
|
2025-07-25 16:26:36 +06:00
|
|
|
return 0;
|
|
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
// 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);
|
2025-07-25 16:26:36 +06:00
|
|
|
} else {
|
2025-07-26 00:32:21 +06:00
|
|
|
x = fifo8_num_used(&mke.info_fifo) ? fifo8_pop(&mke.info_fifo) : 0;
|
2025-07-25 17:23:42 -04:00
|
|
|
// return cdrom_fifo_read(&cdrom.info_fifo);
|
2025-07-26 00:32:21 +06:00
|
|
|
}
|
2025-07-25 17:23:42 -04:00
|
|
|
// pclog("Read FIFO 0x%X, %d\n", x, mke.data_select);
|
2025-07-26 00:32:21 +06:00
|
|
|
return x;
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case 1: // Status
|
2025-07-25 16:26:36 +06:00
|
|
|
/*
|
|
|
|
|
1 = Status Change
|
|
|
|
|
2 = Data Ready
|
|
|
|
|
4 = Response Ready
|
|
|
|
|
8 = Attention / Issue ?
|
|
|
|
|
*/
|
2025-07-25 17:23:42 -04:00
|
|
|
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;
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
2025-07-25 17:23:42 -04:00
|
|
|
case 2: // Data
|
2025-07-27 14:02:37 +06:00
|
|
|
return fifo8_num_used(&mke.data_fifo) ? fifo8_pop(&mke.data_fifo) : 0;
|
2025-07-25 16:26:36 +06:00
|
|
|
case 3:
|
|
|
|
|
return mke.enable_register;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* mke_log("MKE Unknown Read Address: %03x\n",address); */
|
2025-07-25 17:23:42 -04:00
|
|
|
pclog("MKE Unknown Read Address: %03x\n", address);
|
2025-07-25 16:26:36 +06:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0xff;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
void
|
|
|
|
|
mke_close(void *priv)
|
2025-07-25 16:26:36 +06:00
|
|
|
{
|
|
|
|
|
fifo8_destroy(&mke.info_fifo);
|
|
|
|
|
fifo8_destroy(&mke.data_fifo);
|
|
|
|
|
fifo8_destroy(&mke.errors_fifo);
|
2025-07-27 02:17:55 +06:00
|
|
|
timer_disable(&mke.timer);
|
2025-07-25 16:26:36 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mke_cdrom_insert(void *priv)
|
|
|
|
|
{
|
2025-07-25 17:23:42 -04:00
|
|
|
mke_t *dev = (mke_t *) priv;
|
2025-07-25 16:26:36 +06:00
|
|
|
|
|
|
|
|
if ((dev == NULL) || (dev->cdrom_dev == NULL))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (dev->cdrom_dev->ops == NULL) {
|
2025-07-25 17:23:42 -04:00
|
|
|
// dev->unit_attention = 0;
|
2025-07-25 16:26:36 +06:00
|
|
|
dev->cdrom_dev->cd_status = CD_STATUS_EMPTY;
|
2025-07-27 02:17:55 +06:00
|
|
|
if (timer_is_enabled(&dev->timer)) {
|
|
|
|
|
timer_disable(&dev->timer);
|
|
|
|
|
mke.data_to_push = 0;
|
|
|
|
|
fifo8_push(&dev->errors_fifo, 0x15);
|
|
|
|
|
}
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_push(&dev->errors_fifo, 0x11);
|
2025-07-26 00:32:21 +06:00
|
|
|
} else {
|
2025-07-25 17:23:42 -04:00
|
|
|
// dev->unit_attention = 1;
|
2025-07-25 16:26:36 +06:00
|
|
|
/* Turn off the medium changed status. */
|
|
|
|
|
dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION;
|
|
|
|
|
fifo8_push(&dev->errors_fifo, 0x11);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-27 01:42:12 +06:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
void *
|
|
|
|
|
mke_init(const device_t *info)
|
2025-07-25 16:26:36 +06:00
|
|
|
{
|
2025-07-27 02:59:20 +06:00
|
|
|
cdrom_t *dev = NULL;
|
2025-07-25 16:26:36 +06:00
|
|
|
memset(&mke, 0, sizeof(mke_t));
|
|
|
|
|
|
2025-07-26 17:03:23 -04:00
|
|
|
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
2025-07-25 16:26:36 +06:00
|
|
|
if (cdrom[i].bus_type == CDROM_BUS_MKE) {
|
|
|
|
|
dev = &cdrom[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
fifo8_create(&mke.info_fifo, 128);
|
2025-07-27 02:17:55 +06:00
|
|
|
fifo8_create(&mke.data_fifo, 624240 * 2);
|
2025-07-25 16:26:36 +06:00
|
|
|
fifo8_create(&mke.errors_fifo, 8);
|
2025-07-26 00:32:21 +06:00
|
|
|
fifo8_reset(&mke.info_fifo);
|
|
|
|
|
fifo8_reset(&mke.data_fifo);
|
|
|
|
|
fifo8_reset(&mke.errors_fifo);
|
2025-07-25 17:23:42 -04:00
|
|
|
mke.cdrom_dev = dev;
|
2025-07-25 16:26:36 +06:00
|
|
|
mke.command_buffer_pending = 7;
|
2025-07-25 17:23:42 -04:00
|
|
|
mke.sector_type = 0x08 | (1 << 4);
|
|
|
|
|
mke.sector_flags = 0x10;
|
2025-07-27 01:42:12 +06:00
|
|
|
mke.mode_select[2] = 0x08;
|
|
|
|
|
mke.patch0 = 0x01;
|
|
|
|
|
mke.patch1 = 0x02;
|
|
|
|
|
mke.vol0 = 255;
|
|
|
|
|
mke.vol1 = 255;
|
|
|
|
|
dev->sector_size = 2048;
|
2025-07-25 16:26:36 +06:00
|
|
|
|
2025-07-25 17:23:42 -04:00
|
|
|
dev->priv = &mke;
|
|
|
|
|
dev->insert = mke_cdrom_insert;
|
2025-07-27 01:42:12 +06:00
|
|
|
dev->get_volume = mke_get_volume;
|
|
|
|
|
dev->get_channel = mke_get_channel;
|
2025-07-25 16:26:36 +06:00
|
|
|
dev->cached_sector = -1;
|
|
|
|
|
|
2025-07-27 02:17:55 +06:00
|
|
|
timer_add(&mke.timer, mke_command_callback, &mke, 0);
|
2025-07-25 17:33:36 -04:00
|
|
|
uint16_t base = device_get_config_hex16("base");
|
|
|
|
|
io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke);
|
2025-07-25 16:26:36 +06:00
|
|
|
return &mke;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 17:33:36 -04:00
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-25 16:26:36 +06:00
|
|
|
const device_t mke_cdrom_device = {
|
2025-07-27 14:02:37 +06:00
|
|
|
.name = "Panasonic/MKE CD-ROM interface (Creative)",
|
2025-07-25 16:26:36 +06:00
|
|
|
.internal_name = "mkecd",
|
|
|
|
|
.flags = DEVICE_ISA16,
|
|
|
|
|
.local = 0,
|
|
|
|
|
.init = mke_init,
|
|
|
|
|
.close = mke_close,
|
|
|
|
|
.reset = NULL,
|
|
|
|
|
.available = NULL,
|
|
|
|
|
.speed_changed = NULL,
|
|
|
|
|
.force_redraw = NULL,
|
2025-07-25 17:33:36 -04:00
|
|
|
.config = mke_config
|
2025-07-25 16:26:36 +06:00
|
|
|
};
|
2025-07-27 14:02:37 +06:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
};
|