Merge branch '86Box:master' into pot-po-upd
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -121,8 +122,10 @@ static const struct {
|
||||
// clang-format off
|
||||
{ &cdrom_interface_none_device },
|
||||
#ifdef USE_CDROM_MITSUMI
|
||||
{ &mitsumi_cdrom_device },
|
||||
{ &mitsumi_cdrom_device },
|
||||
#endif
|
||||
{ &mke_cdrom_noncreative_device },
|
||||
{ &mke_cdrom_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
862
src/cdrom/cdrom_mke.c
Normal file
862
src/cdrom/cdrom_mke.c
Normal file
@@ -0,0 +1,862 @@
|
||||
/*
|
||||
* 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, <mgrca8@gmail.com>
|
||||
* Kevin Moonlight, <me@yyzkevin.com>
|
||||
* Cacodemon345
|
||||
*
|
||||
* Copyright (C) 2025 Miran Grca.
|
||||
* Copyright (C) 2025 Cacodemon345.
|
||||
* Copyright (C) 2024 Kevin Moonlight.
|
||||
*/
|
||||
#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>
|
||||
#include <86box/ui.h>
|
||||
#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
|
||||
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 vol0, vol1, patch0, patch1;
|
||||
uint8_t mode_select[5];
|
||||
|
||||
uint8_t data_select;
|
||||
uint8_t is_sb;
|
||||
|
||||
uint8_t media_selected; // temporary hack
|
||||
|
||||
Fifo8 data_fifo;
|
||||
Fifo8 info_fifo;
|
||||
Fifo8 errors_fifo;
|
||||
|
||||
cdrom_t *cdrom_dev;
|
||||
|
||||
uint32_t sector_type;
|
||||
uint32_t sector_flags;
|
||||
|
||||
uint32_t unit_attention;
|
||||
|
||||
uint8_t cdbuffer[624240 * 2];
|
||||
|
||||
uint32_t data_to_push;
|
||||
|
||||
pc_timer_t timer;
|
||||
} mke_t;
|
||||
mke_t mke;
|
||||
|
||||
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; \
|
||||
} \
|
||||
}
|
||||
|
||||
static uint8_t temp_buf[65536];
|
||||
|
||||
void
|
||||
mke_get_subq(cdrom_t *dev, uint8_t *b)
|
||||
{
|
||||
cdrom_get_current_subchannel_sony(dev, temp_buf, 1);
|
||||
/* ? */
|
||||
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;
|
||||
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 */
|
||||
|
||||
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 last_track;
|
||||
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536);
|
||||
last_track = temp_buf[3];
|
||||
/* 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;
|
||||
b[2]=ti.number;
|
||||
b[3]=0;
|
||||
b[4]=ti.m;
|
||||
b[5]=ti.s;
|
||||
b[6]=ti.f;
|
||||
b[7]=0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
mke_disc_info(cdrom_t *dev, unsigned char *b)
|
||||
{
|
||||
uint8_t disc_type_buf[34];
|
||||
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];
|
||||
|
||||
b[0] = disc_type_buf[8];
|
||||
b[1] = first_track;
|
||||
b[2] = last_track;
|
||||
b[3] = 0;
|
||||
b[4] = 0;
|
||||
b[5] = 0;
|
||||
blk_to_msf(dev->cdrom_capacity, &b[3]);
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mke_disc_capacity(cdrom_t *dev, unsigned char *b)
|
||||
{
|
||||
b[0] = 0x00;
|
||||
b[1] = 0x00;
|
||||
b[2] = 0x00;
|
||||
b[3] = 0x08;
|
||||
b[4] = 0x00;
|
||||
|
||||
blk_to_msf(dev->cdrom_capacity, &b[0]);
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mke_cdrom_status(cdrom_t *dev, mke_t *mke)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
/*
|
||||
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;
|
||||
/* Always set? */
|
||||
status |= 0x20;
|
||||
status |= STAT_TRAY;
|
||||
if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) {
|
||||
status |= STAT_DISK;
|
||||
status |= STAT_READY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
uint8_t no_multisess[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
fifo8_push_all(&mke->info_fifo, no_multisess, 6);
|
||||
}
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
void
|
||||
mke_command_callback(void *priv)
|
||||
{
|
||||
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));
|
||||
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(mke_t *mke, uint8_t value)
|
||||
{
|
||||
uint16_t i;
|
||||
/* 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[0] == CMD1_ABORT) {
|
||||
mke_log("CMD_ABORT\n");
|
||||
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;
|
||||
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;
|
||||
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_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) {
|
||||
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);
|
||||
}
|
||||
break;
|
||||
} 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("\n");
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} 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);
|
||||
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));
|
||||
break;
|
||||
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));
|
||||
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(&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);
|
||||
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
|
||||
break;
|
||||
case CMD1_READTOC:
|
||||
CHECK_READY();
|
||||
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->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);
|
||||
mke_log("PLAY MSF:");
|
||||
for (i = 0; i < 6; i++) {
|
||||
mke_log("%02x ", mke->command_buffer[i + 1]);
|
||||
}
|
||||
mke_log("\n");
|
||||
{
|
||||
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));
|
||||
}
|
||||
break;
|
||||
case CMD1_SEEK:
|
||||
CHECK_READY();
|
||||
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]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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");
|
||||
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);
|
||||
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");
|
||||
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);
|
||||
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]);
|
||||
break;
|
||||
}
|
||||
} 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 port, uint8_t val, void *priv)
|
||||
{
|
||||
mke_t *mke = (mke_t *) priv;
|
||||
|
||||
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, val);
|
||||
break;
|
||||
case 1:
|
||||
if (mke->is_sb)
|
||||
mke->data_select = val;
|
||||
break;
|
||||
case 2:
|
||||
mke_reset(mke);
|
||||
break;
|
||||
case 3:
|
||||
mke->enable_register = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mke_read(uint16_t port, void *priv)
|
||||
{
|
||||
mke_t *mke = (mke_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
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) : 0x00;
|
||||
else
|
||||
ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0x00;
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
Status:
|
||||
- 1 = Status Change;
|
||||
- 2 = Data Ready;
|
||||
- 4 = Response Ready;
|
||||
- 8 = Attention / Issue?
|
||||
*/
|
||||
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) : 0x00;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
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->cdrom_dev->cd_status = CD_STATUS_EMPTY;
|
||||
if (timer_is_enabled(&dev->timer)) {
|
||||
timer_disable(&dev->timer);
|
||||
dev->data_to_push = 0;
|
||||
fifo8_push(&dev->errors_fifo, 0x15);
|
||||
}
|
||||
fifo8_push(&dev->errors_fifo, 0x11);
|
||||
} else {
|
||||
/* Turn off the medium changed status. */
|
||||
dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION;
|
||||
fifo8_push(&dev->errors_fifo, 0x11);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
mke_get_volume(void *priv, int channel)
|
||||
{
|
||||
mke_t *dev = (mke_t *) priv;
|
||||
|
||||
return channel == 0 ? dev->vol0 : dev->vol1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
mke_get_channel(void *priv, int channel)
|
||||
{
|
||||
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;
|
||||
|
||||
for (uint8_t 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 * 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->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);
|
||||
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 = "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 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format off
|
||||
};
|
||||
|
||||
const device_t mke_cdrom_device = {
|
||||
.name = "Panasonic/MKE CD-ROM interface (Creative)",
|
||||
.internal_name = "mkecd",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 1,
|
||||
.init = mke_init,
|
||||
.close = mke_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.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
|
||||
};
|
||||
@@ -948,6 +948,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);
|
||||
@@ -3127,7 +3128,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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -98,7 +98,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
|
||||
|
||||
24
src/include/86box/cdrom_mke.h
Normal file
24
src/include/86box/cdrom_mke.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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, <mgrca8@gmail.com>
|
||||
* Cacodemon345
|
||||
*
|
||||
* Copyright 2022-2025 Miran Grca.
|
||||
* Copyright 2025 Cacodemon345.
|
||||
*/
|
||||
|
||||
#ifndef CDROM_MKE_H
|
||||
#define CDROM_MKE_H
|
||||
|
||||
extern const device_t mke_cdrom_device;
|
||||
extern const device_t mke_cdrom_noncreative_device;
|
||||
|
||||
#endif /*CDROM_MKE_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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -388,7 +388,7 @@ MachineStatus::iterateCDROM(const std::function<void(int)> &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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<int> 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));
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ 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;
|
||||
bool mke_tracking;
|
||||
};
|
||||
|
||||
#endif // QT_SETTINGS_BUS_TRACKING_HPP
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
@@ -125,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);
|
||||
|
||||
@@ -124,6 +124,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);
|
||||
@@ -147,6 +148,8 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent)
|
||||
ui->tableViewMO->setCurrentIndex(model->index(0, 0));
|
||||
|
||||
Harddrives::populateRemovableBuses(ui->comboBoxRDiskBus->model());
|
||||
if ((ui->comboBoxRDiskBus->model()->rowCount() - 3) > 0)
|
||||
ui->comboBoxRDiskBus->model()->removeRows(3, ui->comboBoxRDiskBus->model()->rowCount() - 3);
|
||||
model = ui->comboBoxRDiskType->model();
|
||||
for (uint32_t i = 0; i < KNOWN_RDISK_DRIVE_TYPES; i++) {
|
||||
Models::AddEntry(model, rdiskDriveTypeName(i), i);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -1534,27 +1536,6 @@ svga_poll(void *priv)
|
||||
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*/
|
||||
if (svga->seqregs[1] & 1)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user