mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
Merge remote-tracking branch 'upstream/master' into feature/ich2
This commit is contained in:
@@ -13,4 +13,4 @@
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c)
|
||||
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c)
|
||||
|
||||
@@ -322,13 +322,13 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bin2bcd (int x)
|
||||
bin2bcd(int x)
|
||||
{
|
||||
return (x % 10) | ((x / 10) << 4);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bcd2bin (int x)
|
||||
bcd2bin(int x)
|
||||
{
|
||||
return (x >> 4) * 10 + (x & 0x0f);
|
||||
}
|
||||
@@ -385,9 +385,9 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
|
||||
} else
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
|
||||
m = (len >> 16) & 0xff;
|
||||
s = (len >> 8) & 0xff;
|
||||
f = len & 0xff;
|
||||
m = (len >> 16) & 0xff;
|
||||
s = (len >> 8) & 0xff;
|
||||
f = len & 0xff;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early)
|
||||
@@ -524,7 +524,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
b[pos++] = subc.index;
|
||||
|
||||
if (msf) {
|
||||
b[pos] = 0;
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
@@ -543,7 +543,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
|
||||
pos += 4;
|
||||
|
||||
b[pos] = 0;
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
@@ -803,7 +803,7 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra
|
||||
return len;
|
||||
}
|
||||
|
||||
/* A new API call for Mitsumi CD-ROM. */
|
||||
/* New API calls for Mitsumi CD-ROM. */
|
||||
void
|
||||
cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
|
||||
{
|
||||
@@ -827,6 +827,64 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
|
||||
memset(buf, 0x00, 9);
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode)
|
||||
{
|
||||
track_info_t ti;
|
||||
int first_track, last_track;
|
||||
|
||||
if (dev != NULL) {
|
||||
dev->ops->get_tracks(dev, &first_track, &last_track);
|
||||
dev->ops->get_track_info(dev, *curtoctrk, 0, &ti);
|
||||
buf[0] = (ti.attr << 4) & 0xf0;
|
||||
buf[1] = ti.number;
|
||||
buf[2] = CD_BCD(*curtoctrk + 1);
|
||||
buf[3] = ti.m;
|
||||
buf[4] = ti.s;
|
||||
buf[5] = ti.f;
|
||||
buf[6] = 0x00;
|
||||
dev->ops->get_track_info(dev, 1, 0, &ti);
|
||||
buf[7] = ti.m;
|
||||
buf[8] = ti.s;
|
||||
buf[9] = ti.f;
|
||||
if (*curtoctrk >= (last_track + 1))
|
||||
*curtoctrk = 0;
|
||||
else if (mode)
|
||||
*curtoctrk = *curtoctrk + 1;
|
||||
} else
|
||||
memset(buf, 0x00, 10);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len)
|
||||
{
|
||||
track_info_t ti;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_DATA_ONLY)
|
||||
return 0;
|
||||
|
||||
cdrom_log("CD-ROM 0: Play Mitsumi audio - %08X %08X\n", pos, len);
|
||||
dev->ops->get_track_info(dev, pos, 0, &ti);
|
||||
pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
dev->ops->get_track_info(dev, len, 1, &ti);
|
||||
len = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
|
||||
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
|
||||
cdrom_stop(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->seek_pos = pos;
|
||||
dev->cd_end = len;
|
||||
dev->cd_status = CD_STATUS_PLAYING;
|
||||
dev->cd_buflen = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type)
|
||||
{
|
||||
|
||||
443
src/cdrom/cdrom_mitsumi.c
Normal file
443
src/cdrom/cdrom_mitsumi.c
Normal file
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2022 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.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_mitsumi.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/sound.h>
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
enum {
|
||||
STAT_CMD_CHECK = 0x01,
|
||||
STAT_PLAY_CDDA = 0x02,
|
||||
STAT_ERROR = 0x04,
|
||||
STAT_DISK_CDDA = 0x08,
|
||||
STAT_SPIN = 0x10,
|
||||
STAT_CHANGE = 0x20,
|
||||
STAT_READY = 0x40,
|
||||
STAT_OPEN = 0x80
|
||||
};
|
||||
enum {
|
||||
CMD_GET_INFO = 0x10,
|
||||
CMD_GET_Q = 0x20,
|
||||
CMD_GET_STAT = 0x40,
|
||||
CMD_SET_MODE = 0x50,
|
||||
CMD_SOFT_RESET = 0x60,
|
||||
CMD_STOPCDDA = 0x70,
|
||||
CMD_CONFIG = 0x90,
|
||||
CMD_SET_VOL = 0xae,
|
||||
CMD_READ1X = 0xc0,
|
||||
CMD_READ2X = 0xc1,
|
||||
CMD_GET_VER = 0xdc,
|
||||
CMD_STOP = 0xf0,
|
||||
CMD_EJECT = 0xf6,
|
||||
CMD_LOCK = 0xfe
|
||||
};
|
||||
enum {
|
||||
MODE_MUTE = 0x01,
|
||||
MODE_GET_TOC = 0x04,
|
||||
MODE_STOP = 0x08,
|
||||
MODE_ECC = 0x20,
|
||||
MODE_DATA = 0x40
|
||||
};
|
||||
enum {
|
||||
DRV_MODE_STOP,
|
||||
DRV_MODE_READ,
|
||||
DRV_MODE_CDDA
|
||||
};
|
||||
enum {
|
||||
FLAG_NODATA = 2,
|
||||
FLAG_NOSTAT = 4,
|
||||
FLAG_UNK = 8, //??
|
||||
FLAG_OPEN = 16
|
||||
};
|
||||
enum {
|
||||
IRQ_DATAREADY = 1,
|
||||
IRQ_DATACOMP = 2,
|
||||
IRQ_ERROR = 4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int dma, irq;
|
||||
int change;
|
||||
int data;
|
||||
uint8_t stat;
|
||||
uint8_t buf[RAW_SECTOR_SIZE];
|
||||
int buf_count;
|
||||
int buf_idx;
|
||||
uint8_t cmdbuf[16];
|
||||
int cmdbuf_count;
|
||||
int cmdrd_count;
|
||||
int cmdbuf_idx;
|
||||
uint8_t mode;
|
||||
uint8_t cmd;
|
||||
uint8_t conf;
|
||||
uint8_t enable_irq;
|
||||
uint8_t enable_dma;
|
||||
uint16_t dmalen;
|
||||
uint32_t readmsf;
|
||||
uint32_t readcount;
|
||||
int locked;
|
||||
int drvmode;
|
||||
int cur_toc_track;
|
||||
int pos;
|
||||
} mcd_t;
|
||||
|
||||
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
|
||||
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
#undef MSFtoLBA
|
||||
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
|
||||
|
||||
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))
|
||||
|
||||
#ifdef ENABLE_MITSUMI_CDROM_LOG
|
||||
int mitsumi_cdrom_do_log = ENABLE_MITSUMI_CDROM_LOG;
|
||||
|
||||
void
|
||||
mitsumi_cdrom_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (mitsumi_cdrom_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define mitsumi_cdrom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_reset(mcd_t *dev)
|
||||
{
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
|
||||
dev->stat = cdrom->host_drive ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 0;
|
||||
dev->buf_count = 0;
|
||||
dev->cur_toc_track = 0;
|
||||
dev->enable_dma = 0;
|
||||
dev->enable_irq = 0;
|
||||
dev->conf = 0;
|
||||
dev->dmalen = COOKED_SECTOR_SIZE;
|
||||
dev->locked = 0;
|
||||
dev->change = 1;
|
||||
dev->data = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
{
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
uint8_t status;
|
||||
int ret;
|
||||
|
||||
if (cdrom == NULL)
|
||||
return 0;
|
||||
|
||||
if (dev->drvmode == DRV_MODE_CDDA) {
|
||||
status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount);
|
||||
if (status == 1)
|
||||
return status;
|
||||
else
|
||||
dev->drvmode = DRV_MODE_READ;
|
||||
}
|
||||
|
||||
if ((dev->enable_irq & IRQ_DATACOMP) && !first) {
|
||||
picint(1 << dev->irq);
|
||||
}
|
||||
if (!dev->readcount) {
|
||||
dev->data = 0;
|
||||
return 0;
|
||||
}
|
||||
cdrom_stop(cdrom);
|
||||
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, &dev->readcount);
|
||||
if (!ret)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff);
|
||||
}
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1);
|
||||
dev->buf_count = dev->dmalen + 1;
|
||||
dev->buf_idx = 0;
|
||||
dev->data = 1;
|
||||
if (dev->enable_dma) {
|
||||
while (dev->pos < dev->readcount) {
|
||||
dma_channel_write(dev->dma, dev->buf[dev->pos]);
|
||||
dev->pos++;
|
||||
}
|
||||
dev->pos = 0;
|
||||
}
|
||||
dev->readcount--;
|
||||
if ((dev->enable_irq & IRQ_DATAREADY) && first)
|
||||
picint(1 << dev->irq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
switch (port & 1) {
|
||||
case 0:
|
||||
if (dev->cmdbuf_count) {
|
||||
dev->cmdbuf_count--;
|
||||
return dev->cmdbuf[dev->cmdbuf_idx++];
|
||||
} else if (dev->buf_count) {
|
||||
ret = (dev->buf_idx < RAW_SECTOR_SIZE) ? dev->buf[dev->buf_idx] : 0;
|
||||
dev->buf_idx++;
|
||||
dev->buf_count--;
|
||||
if (!dev->buf_count)
|
||||
mitsumi_cdrom_read_sector(dev, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return dev->stat;
|
||||
case 1:
|
||||
ret = 0;
|
||||
picintc(1 << dev->irq);
|
||||
if (!dev->buf_count || !dev->data || dev->enable_dma)
|
||||
ret |= FLAG_NODATA;
|
||||
if (!dev->cmdbuf_count)
|
||||
ret |= FLAG_NOSTAT;
|
||||
return ret | FLAG_UNK;
|
||||
}
|
||||
|
||||
return (0xff);
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
|
||||
switch (port & 1) {
|
||||
case 0:
|
||||
if (dev->cmdrd_count) {
|
||||
dev->cmdrd_count--;
|
||||
switch (dev->cmd) {
|
||||
case CMD_SET_MODE:
|
||||
dev->mode = val;
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf_count = 2;
|
||||
break;
|
||||
case CMD_LOCK:
|
||||
dev->locked = val & 1;
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf[2] = 0;
|
||||
dev->cmdbuf_count = 3;
|
||||
break;
|
||||
case CMD_CONFIG:
|
||||
switch (dev->cmdrd_count) {
|
||||
case 0:
|
||||
switch (dev->conf) {
|
||||
case 0x01:
|
||||
dev->dmalen |= val;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->enable_dma = val;
|
||||
break;
|
||||
case 0x10:
|
||||
dev->enable_irq = val;
|
||||
break;
|
||||
}
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf_count = 2;
|
||||
dev->conf = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (dev->conf == 1) {
|
||||
dev->dmalen = val << 8;
|
||||
break;
|
||||
}
|
||||
dev->conf = val;
|
||||
if (dev->conf == 1)
|
||||
dev->cmdrd_count++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
switch (dev->cmdrd_count) {
|
||||
case 0:
|
||||
dev->readcount |= val;
|
||||
mitsumi_cdrom_read_sector(dev, 1);
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_SPIN | STAT_READY;
|
||||
break;
|
||||
case 1:
|
||||
dev->readcount |= (val << 8);
|
||||
break;
|
||||
case 2:
|
||||
dev->readcount = (val << 16);
|
||||
break;
|
||||
case 5:
|
||||
dev->readmsf = 0;
|
||||
case 4:
|
||||
case 3:
|
||||
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!dev->cmdrd_count)
|
||||
dev->stat = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
return;
|
||||
}
|
||||
dev->cmd = val;
|
||||
dev->cmdbuf_idx = 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->data = 0;
|
||||
switch (val) {
|
||||
case CMD_GET_INFO:
|
||||
if (cdrom->host_drive) {
|
||||
cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1]));
|
||||
dev->cmdbuf_count = 10;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_Q:
|
||||
if (cdrom->host_drive) {
|
||||
cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
dev->cmdbuf_count = 11;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_STAT:
|
||||
dev->change = 0;
|
||||
break;
|
||||
case CMD_SET_MODE:
|
||||
dev->cmdrd_count = 1;
|
||||
break;
|
||||
case CMD_STOPCDDA:
|
||||
case CMD_STOP:
|
||||
cdrom_stop(cdrom);
|
||||
dev->drvmode = DRV_MODE_STOP;
|
||||
dev->cur_toc_track = 0;
|
||||
break;
|
||||
case CMD_CONFIG:
|
||||
dev->cmdrd_count = 2;
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
if (cdrom->host_drive) {
|
||||
dev->readcount = 0;
|
||||
dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ;
|
||||
dev->cmdrd_count = 6;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_VER:
|
||||
dev->cmdbuf[1] = 1;
|
||||
dev->cmdbuf[2] = 'D';
|
||||
dev->cmdbuf[3] = 0;
|
||||
dev->cmdbuf_count = 4;
|
||||
break;
|
||||
case CMD_EJECT:
|
||||
cdrom_stop(cdrom);
|
||||
cdrom_eject(0);
|
||||
dev->readcount = 0;
|
||||
break;
|
||||
case CMD_LOCK:
|
||||
dev->cmdrd_count = 1;
|
||||
break;
|
||||
default:
|
||||
dev->cmdbuf[0] = dev->stat | STAT_CMD_CHECK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
mitsumi_cdrom_reset(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
mitsumi_cdrom_init(const device_t *info)
|
||||
{
|
||||
mcd_t *dev;
|
||||
|
||||
dev = malloc(sizeof(mcd_t));
|
||||
memset(dev, 0x00, sizeof(mcd_t));
|
||||
|
||||
dev->irq = 5;
|
||||
dev->dma = 5;
|
||||
|
||||
io_sethandler(0x310, 2,
|
||||
mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev);
|
||||
|
||||
mitsumi_cdrom_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_close(void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
|
||||
if (dev) {
|
||||
free(dev);
|
||||
dev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const device_t mitsumi_cdrom_device = {
|
||||
"Mitsumi CD-ROM interface",
|
||||
"mcd",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
mitsumi_cdrom_init,
|
||||
mitsumi_cdrom_close,
|
||||
NULL,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -56,6 +56,7 @@ enum {
|
||||
CDROM_BUS_DISABLED = 0,
|
||||
CDROM_BUS_ATAPI = 5,
|
||||
CDROM_BUS_SCSI,
|
||||
CDROM_BUS_MITSUMI,
|
||||
CDROM_BUS_USB
|
||||
};
|
||||
|
||||
@@ -145,6 +146,8 @@ extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b);
|
||||
extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type,
|
||||
unsigned char start_track, int msf, int max_len);
|
||||
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
|
||||
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
|
||||
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
|
||||
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf,
|
||||
int cdrom_sector_type, int cdrom_sector_flags, int *len);
|
||||
extern void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type);
|
||||
|
||||
22
src/include/86box/cdrom_mitsumi.h
Normal file
22
src/include/86box/cdrom_mitsumi.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2022 Miran Grca.
|
||||
*/
|
||||
#ifndef CDROM_MITSUMI_H
|
||||
#define CDROM_MITSUMI_H
|
||||
|
||||
extern const device_t mitsumi_cdrom_device;
|
||||
|
||||
#endif /*CDROM_MITSUMI_H*/
|
||||
@@ -32,6 +32,13 @@
|
||||
|
||||
#define TEX_CACHE_MAX 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <atomic>
|
||||
using atomic_int = std::atomic<int>;
|
||||
#else
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
VOODOO_1 = 0,
|
||||
VOODOO_SB50,
|
||||
@@ -170,13 +177,13 @@ typedef struct voodoo_params_t {
|
||||
} voodoo_params_t;
|
||||
|
||||
typedef struct texture_t {
|
||||
uint32_t base;
|
||||
uint32_t tLOD;
|
||||
volatile int refcount, refcount_r[4];
|
||||
int is16;
|
||||
uint32_t palette_checksum;
|
||||
uint32_t addr_start[4], addr_end[4];
|
||||
uint32_t *data;
|
||||
uint32_t base;
|
||||
uint32_t tLOD;
|
||||
atomic_int refcount, refcount_r[4];
|
||||
int is16;
|
||||
uint32_t palette_checksum;
|
||||
uint32_t addr_start[4], addr_end[4];
|
||||
uint32_t *data;
|
||||
} texture_t;
|
||||
|
||||
typedef struct vert_t {
|
||||
@@ -299,19 +306,19 @@ typedef struct voodoo_t {
|
||||
int type;
|
||||
|
||||
fifo_entry_t fifo[FIFO_SIZE];
|
||||
volatile int fifo_read_idx, fifo_write_idx;
|
||||
volatile int cmd_read, cmd_written, cmd_written_fifo;
|
||||
atomic_int fifo_read_idx, fifo_write_idx;
|
||||
atomic_int cmd_read, cmd_written, cmd_written_fifo;
|
||||
|
||||
voodoo_params_t params_buffer[PARAM_SIZE];
|
||||
volatile int params_read_idx[4], params_write_idx;
|
||||
atomic_int params_read_idx[4], params_write_idx;
|
||||
|
||||
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
|
||||
int cmdfifo_rp, cmdfifo_ret_addr;
|
||||
int cmdfifo_in_sub;
|
||||
volatile int cmdfifo_depth_rd, cmdfifo_depth_wr;
|
||||
volatile int cmdfifo_enabled;
|
||||
uint32_t cmdfifo_amin, cmdfifo_amax;
|
||||
int cmdfifo_holecount;
|
||||
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
|
||||
int cmdfifo_rp, cmdfifo_ret_addr;
|
||||
int cmdfifo_in_sub;
|
||||
atomic_int cmdfifo_depth_rd, cmdfifo_depth_wr;
|
||||
atomic_int cmdfifo_enabled;
|
||||
uint32_t cmdfifo_amin, cmdfifo_amax;
|
||||
int cmdfifo_holecount;
|
||||
|
||||
uint32_t sSetupMode;
|
||||
vert_t verts[4];
|
||||
|
||||
@@ -4426,7 +4426,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_IDE,
|
||||
.flags = 0,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 32768,
|
||||
|
||||
@@ -518,7 +518,9 @@ esp_dma_enable(esp_t *dev, int level)
|
||||
esp_log("ESP DMA Enabled\n");
|
||||
dev->dma_enabled = 1;
|
||||
dev->dma_86c01.status |= 0x02;
|
||||
if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) {
|
||||
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);
|
||||
} else {
|
||||
esp_log("Period = %lf\n", dev->period);
|
||||
@@ -924,6 +926,7 @@ esp_write_response(esp_t *dev)
|
||||
|
||||
buf[0] = dev->status;
|
||||
buf[1] = 0;
|
||||
esp_log("esp_write_response(): %02X %02X\n", buf[0], buf[1]);
|
||||
|
||||
if (dev->dma) {
|
||||
if (dev->mca) {
|
||||
@@ -953,10 +956,13 @@ esp_callback(void *p)
|
||||
{
|
||||
esp_t *dev = (esp_t *) p;
|
||||
|
||||
if (dev->dma_enabled || dev->do_cmd) {
|
||||
if (dev->dma_enabled || dev->do_cmd || ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD)) {
|
||||
if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) {
|
||||
esp_log("ESP SCSI Handle TI Callback\n");
|
||||
handle_ti(dev);
|
||||
} else if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD) {
|
||||
esp_log("ESP SCSI Handle PAD Callback\n");
|
||||
handle_ti(dev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,6 +1090,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
|
||||
}
|
||||
break;
|
||||
case CMD_TI:
|
||||
esp_log("val = %02X\n", val);
|
||||
break;
|
||||
case CMD_SEL:
|
||||
handle_s_without_atn(dev);
|
||||
@@ -1107,9 +1114,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
|
||||
esp_raise_irq(dev);
|
||||
break;
|
||||
case CMD_PAD:
|
||||
dev->rregs[ESP_RSTAT] = STAT_TC;
|
||||
dev->rregs[ESP_RINTR] |= INTR_FC;
|
||||
dev->rregs[ESP_RSEQ] = 0;
|
||||
esp_log("val = %02X\n", val);
|
||||
timer_stop(&dev->timer);
|
||||
timer_on_auto(&dev->timer, dev->period);
|
||||
esp_log("ESP Transfer Pad\n");
|
||||
break;
|
||||
case CMD_SATN:
|
||||
@@ -1173,6 +1180,9 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
|
||||
} else {
|
||||
dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4);
|
||||
}
|
||||
esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len,
|
||||
ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3],
|
||||
buf[0], buf[1], buf[2], buf[3]);
|
||||
|
||||
/* update status registers */
|
||||
dev->dma_regs[DMA_WBC] -= len;
|
||||
@@ -1215,6 +1225,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
|
||||
switch (val & DMA_CMD_MASK) {
|
||||
case 0: /*IDLE*/
|
||||
esp_dma_enable(dev, 0);
|
||||
esp_log("PCI DMA disable\n");
|
||||
break;
|
||||
case 1: /*BLAST*/
|
||||
break;
|
||||
@@ -1227,6 +1238,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
|
||||
dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA];
|
||||
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\n");
|
||||
break;
|
||||
default: /* can't happen */
|
||||
abort();
|
||||
|
||||
@@ -670,7 +670,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
if ((svga->seqaddr == 2) && !gd54xx->unlocked) {
|
||||
o = svga->seqregs[svga->seqaddr & 0x1f];
|
||||
svga_out(addr, val, svga);
|
||||
svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f);
|
||||
if (svga->gdcreg[0xb] & 0x04)
|
||||
svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f);
|
||||
return;
|
||||
} else if ((svga->seqaddr > 6) && !gd54xx->unlocked)
|
||||
return;
|
||||
@@ -878,10 +879,6 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
if (svga->gdcreg[0xb] & 0x04)
|
||||
svga->writemode = svga->gdcreg[5] & 7;
|
||||
else
|
||||
svga->writemode = svga->gdcreg[5] & 3;
|
||||
svga->adv_flags = 0;
|
||||
if (svga->gdcreg[0xb] & 0x01)
|
||||
svga->adv_flags = FLAG_EXTRA_BANKS;
|
||||
@@ -893,6 +890,18 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->adv_flags |= FLAG_LATCH8;
|
||||
if (svga->gdcreg[0xb] & 0x10)
|
||||
svga->adv_flags |= FLAG_ADDR_BY16;
|
||||
if (svga->gdcreg[0xb] & 0x04)
|
||||
svga->writemode = svga->gdcreg[5] & 7;
|
||||
else {
|
||||
svga->gdcreg[5] &= ~0x04;
|
||||
svga->writemode = svga->gdcreg[5] & 3;
|
||||
svga->adv_flags = 0;
|
||||
svga->gdcreg[0] &= 0x0f;
|
||||
gd543x_mmio_write(0xb8000, svga->gdcreg[0], gd54xx);
|
||||
svga->gdcreg[1] &= 0x0f;
|
||||
gd543x_mmio_write(0xb8004, svga->gdcreg[1], gd54xx);
|
||||
svga->seqregs[2] &= 0x0f;
|
||||
}
|
||||
gd54xx_recalc_banking(gd54xx);
|
||||
break;
|
||||
|
||||
|
||||
@@ -639,7 +639,7 @@ MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \
|
||||
minivhd_struct_rw.o minivhd_util.o
|
||||
|
||||
CDROMOBJ := cdrom.o \
|
||||
cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o
|
||||
cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o
|
||||
|
||||
ZIPOBJ := zip.o
|
||||
|
||||
|
||||
Reference in New Issue
Block a user