sync 2.2.0

parent 516bc4b6
/* /*
* UAE - The Un*x Amiga Emulator * UAE - The Un*x Amiga Emulator
* *
* CD32 Akiko emulation * CD32 Akiko emulation
* *
* - C2P * - C2P
* - NVRAM * - NVRAM
* - CDROM * - CDROM
* *
* Copyright 2001-2009 Toni Wilen * Copyright 2001-2009 Toni Wilen
* *
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
...@@ -82,55 +82,55 @@ static void nvram_write (unsigned int offset, unsigned int len) ...@@ -82,55 +82,55 @@ static void nvram_write (unsigned int offset, unsigned int len)
if (!currprefs.cs_cd32nvram) if (!currprefs.cs_cd32nvram)
return; return;
f = zfile_fopen (currprefs.flashfile, "rb+", ZFD_NORMAL); f = zfile_fopen (currprefs.flashfile, "rb+", ZFD_NORMAL);
if (!f) { if (!f) {
f = zfile_fopen (currprefs.flashfile, "wb", 0); f = zfile_fopen (currprefs.flashfile, "wb", 0);
if (!f) return; if (!f) return;
zfile_fwrite (cd32_nvram, NVRAM_SIZE, 1, f); zfile_fwrite (cd32_nvram, NVRAM_SIZE, 1, f);
} }
zfile_fseek (f, offset, SEEK_SET); zfile_fseek (f, offset, SEEK_SET);
zfile_fwrite (cd32_nvram + offset, len, 1, f); zfile_fwrite (cd32_nvram + offset, len, 1, f);
zfile_fclose (f); zfile_fclose (f);
} }
static void nvram_read (void) static void nvram_read (void)
{ {
struct zfile *f; struct zfile *f;
if (!currprefs.cs_cd32nvram) if (!currprefs.cs_cd32nvram)
return; return;
f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL); f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
memset (cd32_nvram, 0, NVRAM_SIZE); memset (cd32_nvram, 0, NVRAM_SIZE);
if (!f) return; if (!f) return;
zfile_fread (cd32_nvram, NVRAM_SIZE, 1, f); zfile_fread (cd32_nvram, NVRAM_SIZE, 1, f);
zfile_fclose (f); zfile_fclose (f);
} }
static void i2c_do (void) static void i2c_do (void)
{ {
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
int i; int i;
#endif #endif
sda_in = 1; sda_in = 1;
if (!sda_dir_nvram && scl_out && oscl) { if (!sda_dir_nvram && scl_out && oscl) {
if (!sda_out && osda) { /* START-condition? */ if (!sda_out && osda) { /* START-condition? */
state = I2C_DEVICEADDR; state = I2C_DEVICEADDR;
bitcounter = 0; bitcounter = 0;
direction = -1; direction = -1;
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
write_log ("START\n"); write_log ("START\n");
#endif #endif
return; return;
} else if(sda_out && !osda) { /* STOP-condition? */ } else if(sda_out && !osda) { /* STOP-condition? */
state = I2C_WAIT; state = I2C_WAIT;
bitcounter = -1; bitcounter = -1;
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
write_log ("STOP\n"); write_log ("STOP\n");
#endif #endif
if (direction > 0) { if (direction > 0) {
memcpy (cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), nvram_writetmp, NVRAM_PAGE_SIZE); memcpy (cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), nvram_writetmp, NVRAM_PAGE_SIZE);
nvram_write (nvram_address & ~(NVRAM_PAGE_SIZE - 1), NVRAM_PAGE_SIZE); nvram_write (nvram_address & ~(NVRAM_PAGE_SIZE - 1), NVRAM_PAGE_SIZE);
direction = -1; direction = -1;
gui_flicker_led (LED_MD, 0, 2); gui_flicker_led (LED_MD, 0, 2);
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
write_log ("NVRAM write address %04X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1)); write_log ("NVRAM write address %04X:", nvram_address & ~(NVRAM_PAGE_SIZE - 1));
for (i = 0; i < NVRAM_PAGE_SIZE; i++) for (i = 0; i < NVRAM_PAGE_SIZE; i++)
...@@ -138,38 +138,38 @@ static void i2c_do (void) ...@@ -138,38 +138,38 @@ static void i2c_do (void)
write_log ("\n"); write_log ("\n");
#endif #endif
} }
return; return;
} }
} }
if (bitcounter >= 0) { if (bitcounter >= 0) {
if (direction) { if (direction) {
/* Amiga -> NVRAM */ /* Amiga -> NVRAM */
if (scl_out && !oscl) { if (scl_out && !oscl) {
if (bitcounter == 8) { if (bitcounter == 8) {
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
write_log ("RB %02X ", nvram_byte, M68K_GETPC); write_log ("RB %02X ", nvram_byte, M68K_GETPC);
#endif #endif
sda_in = 0; /* ACK */ sda_in = 0; /* ACK */
if (direction > 0) { if (direction > 0) {
nvram_writetmp[nvram_writeaddr++] = nvram_byte; nvram_writetmp[nvram_writeaddr++] = nvram_byte;
nvram_writeaddr &= 15; nvram_writeaddr &= 15;
bitcounter = 0; bitcounter = 0;
} else { } else {
bitcounter = -1; bitcounter = -1;
} }
} else { } else {
//write_log ("NVRAM received bit %d, offset %d\n", sda_out, bitcounter); //write_log (L"NVRAM received bit %d, offset %d\n", sda_out, bitcounter);
nvram_byte <<= 1; nvram_byte <<= 1;
nvram_byte |= sda_out; nvram_byte |= sda_out;
bitcounter++; bitcounter++;
} }
} }
} else { } else {
/* NVRAM -> Amiga */ /* NVRAM -> Amiga */
if (scl_out && !oscl && bitcounter < 8) { if (scl_out && !oscl && bitcounter < 8) {
if (bitcounter == 0) if (bitcounter == 0)
nvram_byte = cd32_nvram[nvram_address]; nvram_byte = cd32_nvram[nvram_address];
sda_dir_nvram = 1; sda_dir_nvram = 1;
sda_in = (nvram_byte & 0x80) ? 1 : 0; sda_in = (nvram_byte & 0x80) ? 1 : 0;
//write_log ("NVRAM sent bit %d, offset %d\n", sda_in, bitcounter); //write_log ("NVRAM sent bit %d, offset %d\n", sda_in, bitcounter);
...@@ -179,35 +179,35 @@ static void i2c_do (void) ...@@ -179,35 +179,35 @@ static void i2c_do (void)
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
write_log ("NVRAM sent byte %02X address %04X PC=%08X\n", cd32_nvram[nvram_address], nvram_address, M68K_GETPC); write_log ("NVRAM sent byte %02X address %04X PC=%08X\n", cd32_nvram[nvram_address], nvram_address, M68K_GETPC);
#endif #endif
nvram_address++; nvram_address++;
nvram_address &= NVRAM_SIZE - 1; nvram_address &= NVRAM_SIZE - 1;
sda_dir_nvram = 0; sda_dir_nvram = 0;
} }
} }
if(!sda_out && sda_dir && !scl_out) /* ACK from Amiga */ if(!sda_out && sda_dir && !scl_out) /* ACK from Amiga */
bitcounter = 0; bitcounter = 0;
} }
if (bitcounter >= 0) return; if (bitcounter >= 0) return;
} }
switch (state) switch (state)
{ {
case I2C_DEVICEADDR: case I2C_DEVICEADDR:
if ((nvram_byte & 0xf0) != 0xa0) { if ((nvram_byte & 0xf0) != 0xa0) {
write_log ("WARNING: I2C_DEVICEADDR: device address != 0xA0\n"); write_log ("WARNING: I2C_DEVICEADDR: device address != 0xA0\n");
state = I2C_WAIT; state = I2C_WAIT;
return; return;
} }
nvram_rw = (nvram_byte & 1) ? 0 : 1; nvram_rw = (nvram_byte & 1) ? 0 : 1;
if (nvram_rw) { if (nvram_rw) {
/* 2 high address bits, only fetched if WRITE = 1 */ /* 2 high address bits, only fetched if WRITE = 1 */
nvram_address &= 0xff; nvram_address &= 0xff;
nvram_address |= ((nvram_byte >> 1) & 3) << 8; nvram_address |= ((nvram_byte >> 1) & 3) << 8;
state = I2C_WORDADDR; state = I2C_WORDADDR;
direction = -1; direction = -1;
} else { } else {
state = I2C_DATA; state = I2C_DATA;
direction = 0; direction = 0;
sda_dir_nvram = 1; sda_dir_nvram = 1;
} }
bitcounter = 0; bitcounter = 0;
#if AKIKO_DEBUG_NVRAM #if AKIKO_DEBUG_NVRAM
...@@ -221,15 +221,15 @@ static void i2c_do (void) ...@@ -221,15 +221,15 @@ static void i2c_do (void)
write_log ("I2C_WORDADDR: address %04X PC=%08X\n", nvram_address, M68K_GETPC); write_log ("I2C_WORDADDR: address %04X PC=%08X\n", nvram_address, M68K_GETPC);
#endif #endif
if (direction < 0) { if (direction < 0) {
memcpy (nvram_writetmp, cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), NVRAM_PAGE_SIZE); memcpy (nvram_writetmp, cd32_nvram + (nvram_address & ~(NVRAM_PAGE_SIZE - 1)), NVRAM_PAGE_SIZE);
nvram_writeaddr = nvram_address & (NVRAM_PAGE_SIZE - 1); nvram_writeaddr = nvram_address & (NVRAM_PAGE_SIZE - 1);
gui_flicker_led (LED_MD, 0, 1); gui_flicker_led (LED_MD, 0, 1);
} }
state = I2C_DATA; state = I2C_DATA;
bitcounter = 0; bitcounter = 0;
direction = 1; direction = 1;
break; break;
} }
} }
static void akiko_nvram_write (int offset, uae_u32 v) static void akiko_nvram_write (int offset, uae_u32 v)
...@@ -292,42 +292,42 @@ static uae_u32 akiko_result[8]; ...@@ -292,42 +292,42 @@ static uae_u32 akiko_result[8];
static void akiko_c2p_do (void) static void akiko_c2p_do (void)
{ {
int i; int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
akiko_result[i] = 0; akiko_result[i] = 0;
/* FIXME: better c2p algoritm than this piece of crap.... */ /* FIXME: better c2p algoritm than this piece of crap.... */
for (i = 0; i < 8 * 32; i++) { for (i = 0; i < 8 * 32; i++) {
if (akiko_buffer[7 - (i >> 5)] & (1 << (i & 31))) if (akiko_buffer[7 - (i >> 5)] & (1 << (i & 31)))
akiko_result[i & 7] |= 1 << (i >> 3); akiko_result[i & 7] |= 1 << (i >> 3);
} }
} }
static void akiko_c2p_write (int offset, uae_u32 v) static void akiko_c2p_write (int offset, uae_u32 v)
{ {
if (offset == 3) if (offset == 3)
akiko_buffer[akiko_write_offset] = 0; akiko_buffer[akiko_write_offset] = 0;
akiko_buffer[akiko_write_offset] |= v << ( 8 * (3 - offset)); akiko_buffer[akiko_write_offset] |= v << ( 8 * (3 - offset));
if (offset == 0) { if (offset == 0) {
akiko_write_offset++; akiko_write_offset++;
akiko_write_offset &= 7; akiko_write_offset &= 7;
} }
akiko_read_offset = 0; akiko_read_offset = 0;
} }
static uae_u32 akiko_c2p_read (int offset) static uae_u32 akiko_c2p_read (int offset)
{ {
uae_u32 v; uae_u32 v;
if (akiko_read_offset == 0 && offset == 3) if (akiko_read_offset == 0 && offset == 3)
akiko_c2p_do (); akiko_c2p_do ();
akiko_write_offset = 0; akiko_write_offset = 0;
v = akiko_result[akiko_read_offset]; v = akiko_result[akiko_read_offset];
if (offset == 0) { if (offset == 0) {
akiko_read_offset++; akiko_read_offset++;
akiko_read_offset &= 7; akiko_read_offset &= 7;
} }
return v >> (8 * (3 - offset)); return v >> (8 * (3 - offset));
} }
/* CD32 CDROM hardware emulation /* CD32 CDROM hardware emulation
...@@ -390,11 +390,11 @@ static uae_u8 cdrom_result_buffer[32]; ...@@ -390,11 +390,11 @@ static uae_u8 cdrom_result_buffer[32];
static uae_u8 cdrom_command_buffer[32]; static uae_u8 cdrom_command_buffer[32];
static uae_u8 cdrom_command; static uae_u8 cdrom_command;
#define MAX_TOC_ENTRIES 103 /* tracks 1-99, A0,A1 and A2 */ #define MAX_TOC_ENTRIES 103 /* tracks 1-99, A0, A1 and A2 */
static int cdrom_toc_entries; static int cdrom_toc_entries;
static int cdrom_toc_counter; static int cdrom_toc_counter;
static uae_u32 cdrom_toc_crc; static uae_u32 cdrom_toc_crc;
static uae_u8 cdrom_toc_buffer[MAX_TOC_ENTRIES*13]; static uae_u8 cdrom_toc_buffer[MAX_TOC_ENTRIES * 13];
static uae_u8 cdrom_toc_cd_buffer[4 + MAX_TOC_ENTRIES * 11]; static uae_u8 cdrom_toc_cd_buffer[4 + MAX_TOC_ENTRIES * 11];
static uae_u8 qcode_buf[12]; static uae_u8 qcode_buf[12];
static int qcode_valid; static int qcode_valid;
...@@ -415,7 +415,7 @@ static int cd_initialized; ...@@ -415,7 +415,7 @@ static int cd_initialized;
static uae_u8 *sector_buffer_1, *sector_buffer_2; static uae_u8 *sector_buffer_1, *sector_buffer_2;
static int sector_buffer_sector_1, sector_buffer_sector_2; static int sector_buffer_sector_1, sector_buffer_sector_2;
#define SECTOR_BUFFER_SIZE 64 #define SECTOR_BUFFER_SIZE 64
static uae_u8 *sector_buffer_info_1, *sector_buffer_info_2; static uae_u8 *sector_buffer_info_1, *sector_buffer_info_2;
static int unitnum = -1; static int unitnum = -1;
...@@ -448,37 +448,37 @@ void rethink_akiko (void) ...@@ -448,37 +448,37 @@ void rethink_akiko (void)
static uae_u8 frombcd (uae_u8 v) static uae_u8 frombcd (uae_u8 v)
{ {
return (v >> 4) * 10 + (v & 15); return (v >> 4) * 10 + (v & 15);
} }
static uae_u8 tobcd (uae_u8 v) static uae_u8 tobcd (uae_u8 v)
{ {
return ((v / 10) << 4) | (v % 10); return ((v / 10) << 4) | (v % 10);
} }
static int fromlongbcd (uae_u8 *p) static int fromlongbcd (uae_u8 *p)
{ {
return (frombcd (p[0]) << 16) | (frombcd (p[1]) << 8) | (frombcd (p[2]) << 0); return (frombcd (p[0]) << 16) | (frombcd (p[1]) << 8) | (frombcd (p[2]) << 0);
} }
/* convert minutes, seconds and frames -> logical sector number */ /* convert minutes, seconds and frames -> logical sector number */
static int msf2lsn (int msf) static int msf2lsn (int msf)
{ {
int sector = (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff)) - 150; int sector = (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff)) - 150;
if (sector < 0) if (sector < 0)
sector = 0; sector = 0;
return sector; return sector;
} }
/* convert logical sector number -> minutes, seconds and frames */ /* convert logical sector number -> minutes, seconds and frames */
static int lsn2msf (int sectors) static int lsn2msf (int sectors)
{ {
int msf; int msf;
sectors += 150; sectors += 150;
msf = (sectors / (75 * 60)) << 16; msf = (sectors / (75 * 60)) << 16;
msf |= ((sectors / 75) % 60) << 8; msf |= ((sectors / 75) % 60) << 8;
msf |= (sectors % 75) << 0; msf |= (sectors % 75) << 0;
return msf; return msf;
} }
static void cdaudiostop_do (void) static void cdaudiostop_do (void)
...@@ -493,8 +493,8 @@ static void cdaudiostop_do (void) ...@@ -493,8 +493,8 @@ static void cdaudiostop_do (void)
static void cdaudiostop (void) static void cdaudiostop (void)
{ {
cdrom_playing = 0; cdrom_playing = 0;
cdrom_paused = 0; cdrom_paused = 0;
cdrom_audiotimeout = 0; cdrom_audiotimeout = 0;
write_comm_pipe_u32 (&requests, 0x104, 1); write_comm_pipe_u32 (&requests, 0x104, 1);
} }
...@@ -505,7 +505,7 @@ static void cdaudioplay_do (void) ...@@ -505,7 +505,7 @@ static void cdaudioplay_do (void)
uae_u32 endmsf = read_comm_pipe_u32_blocking (&requests); uae_u32 endmsf = read_comm_pipe_u32_blocking (&requests);
uae_u32 scan = read_comm_pipe_u32_blocking (&requests); uae_u32 scan = read_comm_pipe_u32_blocking (&requests);
qcode_valid = 0; qcode_valid = 0;
if (unitnum < 0) if (unitnum < 0)
return; return;
sys_command_cd_play (DF_IOCTL, unitnum, startmsf, endmsf, scan); sys_command_cd_play (DF_IOCTL, unitnum, startmsf, endmsf, scan);
} }
...@@ -552,72 +552,72 @@ static int cd_qcode (uae_u8 *d) ...@@ -552,72 +552,72 @@ static int cd_qcode (uae_u8 *d)
const uae_u8 *buf, *s; const uae_u8 *buf, *s;
uae_u8 as; uae_u8 as;
if (d) if (d)
memset (d, 0, 11); memset (d, 0, 11);
last_play_pos = 0; last_play_pos = 0;
if (!qcode_valid) if (!qcode_valid)
return 0; return 0;
buf = qcode_buf; buf = qcode_buf;
as = buf[1]; as = buf[1];
if (as != 0x11 && as != 0x12 && as != 0x13 && as != 0x15) /* audio status ok? */ if (as != 0x11 && as != 0x12 && as != 0x13 && as != 0x15) /* audio status ok? */
return 0; return 0;
s = buf + 4; s = buf + 4;
last_play_pos = (s[5] << 16) | (s[6] << 8) | (s[7] << 0); last_play_pos = (s[5] << 16) | (s[6] << 8) | (s[7] << 0);
if (!d) if (!d)
return 0; return 0;
/* ??? */ /* ??? */
d[0] = 0; d[0] = 0;
/* CtlAdr */ /* CtlAdr */
d[1] = (s[1] >> 4) | (s[1] << 4); d[1] = (s[1] >> 4) | (s[1] << 4);
/* Track */ /* Track */
d[2] = tobcd (s[2]); d[2] = tobcd (s[2]);
/* Index */ /* Index */
d[3] = tobcd (s[3]); d[3] = tobcd (s[3]);
/* TrackPos */ /* TrackPos */
d[4] = tobcd (s[9]); d[4] = tobcd (s[9]);
d[5] = tobcd (s[10]); d[5] = tobcd (s[10]);
d[6] = tobcd (s[11]); d[6] = tobcd (s[11]);
/* DiskPos */ /* DiskPos */
d[7] = 0; d[7] = 0;
d[8] = tobcd (s[5]); d[8] = tobcd (s[5]);
d[9] = tobcd (s[6]); d[9] = tobcd (s[6]);
d[10] = tobcd (s[7]); d[10] = tobcd (s[7]);
if (as == 0x15) { if (as == 0x15) {
/* Make sure end of disc position is not missed. /* Make sure end of disc position is not missed.
*/ */
int lsn = msf2lsn ((s[5] << 16) | (s[6] << 8) | (s[7] << 0)); int lsn = msf2lsn ((s[5] << 16) | (s[6] << 8) | (s[7] << 0));
int msf = lsn2msf (cdrom_leadout); int msf = lsn2msf (cdrom_leadout);
if (lsn >= cdrom_leadout || cdrom_leadout - lsn < 10) { if (lsn >= cdrom_leadout || cdrom_leadout - lsn < 10) {
d[8] = tobcd ((uae_u8)(msf >> 16)); d[8] = tobcd ((uae_u8)(msf >> 16));
d[9] = tobcd ((uae_u8)(msf >> 8)); d[9] = tobcd ((uae_u8)(msf >> 8));
d[10] = tobcd ((uae_u8)(msf >> 0)); d[10] = tobcd ((uae_u8)(msf >> 0));
} }
} }
return 0; return 0;
} }
/* read toc */ /* read toc */
static int cdrom_toc (void) static int cdrom_toc (void)
{ {
int i, j; int i, j;
int datatrack = 0, secondtrack = 0; int datatrack = 0, secondtrack = 0;
uae_u8 *d; uae_u8 *d;
const uae_u8 *buf, *s; const uae_u8 *buf, *s;
cdrom_toc_counter = -1; cdrom_toc_counter = -1;
cdrom_toc_entries = 0; cdrom_toc_entries = 0;
buf = sys_command_cd_toc (DF_IOCTL, unitnum); buf = sys_command_cd_toc (DF_IOCTL, unitnum);
if (!buf) if (!buf)
return 1; return 1;
i = (buf[0] << 8) | (buf[1] << 0); i = (buf[0] << 8) | (buf[1] << 0);
i -= 2; i -= 2;
i /= 11; i /= 11;
if (i > MAX_TOC_ENTRIES) if (i > MAX_TOC_ENTRIES)
return -1; return -1;
cdrom_toc_entries = i; cdrom_toc_entries = i;
memset (cdrom_toc_buffer, 0, MAX_TOC_ENTRIES * 13); memset (cdrom_toc_buffer, 0, MAX_TOC_ENTRIES * 13);
memcpy (cdrom_toc_cd_buffer, buf, 4 + cdrom_toc_entries * 11); memcpy (cdrom_toc_cd_buffer, buf, 4 + cdrom_toc_entries * 11);
cdrom_data_end = -1; cdrom_data_end = -1;
for (j = 0; j < cdrom_toc_entries; j++) { for (j = 0; j < cdrom_toc_entries; j++) {
uae_u32 addr; uae_u32 addr;
s = buf + 4 + j * 11; s = buf + 4 + j * 11;
...@@ -629,46 +629,46 @@ static int cdrom_toc (void) ...@@ -629,46 +629,46 @@ static int cdrom_toc (void)
d[9] = tobcd (s[9]); d[9] = tobcd (s[9]);
d[10] = tobcd (s[10]); d[10] = tobcd (s[10]);
if (s[3] == 1 && (s[1] & 0x0c) == 0x04) if (s[3] == 1 && (s[1] & 0x0c) == 0x04)
datatrack = 1; datatrack = 1;
if (s[3] == 2) if (s[3] == 2)
secondtrack = addr; secondtrack = addr;
if (s[3] == 0xa2) if (s[3] == 0xa2)
cdrom_leadout = addr; cdrom_leadout = addr;
} }
cdrom_toc_crc = get_crc32(cdrom_toc_buffer, cdrom_toc_entries * 13); cdrom_toc_crc = get_crc32(cdrom_toc_buffer, cdrom_toc_entries * 13);
if (datatrack) { if (datatrack) {
if (secondtrack) if (secondtrack)
cdrom_data_end = secondtrack; cdrom_data_end = secondtrack;
else else
cdrom_data_end = cdrom_leadout; cdrom_data_end = cdrom_leadout;
} }
return 0; return 0;
} }
/* open device */ /* open device */
static int sys_cddev_open (void) static int sys_cddev_open (void)
{ {
int first = -1; int first = -1;
struct device_info di1, *di2; struct device_info di1, *di2;
int cd32unit = -1; int cd32unit = -1;
int audiounit = -1; int audiounit = -1;
int opened[MAX_TOTAL_DEVICES]; int opened[MAX_TOTAL_DEVICES];
int i; int i;
for (unitnum = 0; unitnum < MAX_TOTAL_DEVICES; unitnum++) { for (unitnum = 0; unitnum < MAX_TOTAL_DEVICES; unitnum++) {
opened[unitnum] = 0; opened[unitnum] = 0;
if (sys_command_open (DF_IOCTL, unitnum)) { if (sys_command_open (DF_IOCTL, unitnum)) {
opened[unitnum] = 1; opened[unitnum] = 1;
di2 = sys_command_info (DF_IOCTL, unitnum, &di1); di2 = sys_command_info (DF_IOCTL, unitnum, &di1);
if (di2 && di2->type == INQ_ROMD) { if (di2 && di2->type == INQ_ROMD) {
write_log ("%s: ", di2->label); write_log ("%s: ", di2->label);
if (first < 0) if (first < 0)
first = unitnum; first = unitnum;
if (!cdrom_toc ()) { if (!cdrom_toc ()) {
if (cdrom_data_end > 0) { if (cdrom_data_end > 0) {
uae_u8 *p = sys_command_cd_read (DF_IOCTL, unitnum, 16); uae_u8 *p = sys_command_cd_read (DF_IOCTL, unitnum, 16);
if (p) { if (p) {
if (!memcmp (p + 8, "CDTV", 4) || !memcmp (p + 8, "CD32", 4)) { if (!memcmp (p + 8, "CDTV", 4) || !memcmp (p + 8, "CD32", 4)) {
uae_u32 crc; uae_u32 crc;
write_log ("CD32 or CDTV"); write_log ("CD32 or CDTV");
if (cd32unit < 0) if (cd32unit < 0)
...@@ -678,27 +678,27 @@ static int sys_cddev_open (void) ...@@ -678,27 +678,27 @@ static int sys_cddev_open (void)
if (crc == 0xe56c340f) if (crc == 0xe56c340f)
write_log (" [CD32.TM]"); write_log (" [CD32.TM]");
write_log ("\n"); write_log ("\n");
} else { } else {
write_log ("non CD32/CDTV data CD\n"); write_log ("non CD32/CDTV data CD\n");
} }
} else { } else {
write_log ("read error\n"); write_log ("read error\n");
} }
} else { } else {
write_log ("Audio CD\n"); write_log ("Audio CD\n");
if (audiounit < 0) if (audiounit < 0)
audiounit = unitnum; audiounit = unitnum;
} }
} else { } else {
write_log ("can't read TOC\n"); write_log ("can't read TOC\n");
} }
} }
} }
} }
unitnum = audiounit; unitnum = audiounit;
if (cd32unit >= 0) if (cd32unit >= 0)
unitnum = cd32unit; unitnum = cd32unit;
if (unitnum < 0) if (unitnum < 0)
unitnum = first; unitnum = first;
if (unitnum >= 0) if (unitnum >= 0)
opened[unitnum] = 0; opened[unitnum] = 0;
...@@ -706,27 +706,27 @@ static int sys_cddev_open (void) ...@@ -706,27 +706,27 @@ static int sys_cddev_open (void)
if (opened[i]) if (opened[i])
sys_command_close (DF_IOCTL, i); sys_command_close (DF_IOCTL, i);
} }
if (unitnum < 0) if (unitnum < 0)
return 1; return 1;
di2 = sys_command_info (DF_IOCTL, unitnum, &di1); di2 = sys_command_info (DF_IOCTL, unitnum, &di1);
if (!di2) { if (!di2) {
write_log ("unit %d info failed\n", unitnum); write_log ("unit %d info failed\n", unitnum);
sys_command_close (DF_IOCTL, unitnum); sys_command_close (DF_IOCTL, unitnum);
return 1; return 1;
} }
if (!sys_command_ismedia (DF_IOCTL, unitnum, 0)) if (sys_command_ismedia (DF_IOCTL, unitnum, 0) <= 0)
cd_hunt = 1; cd_hunt = 1;
write_log ("using drive %s (unit %d, media %d)\n", di2->label, unitnum, di2->media_inserted); write_log ("using drive %s (unit %d, media %d)\n", di2->label, unitnum, di2->media_inserted);
/* make sure CD audio is not playing */ /* make sure CD audio is not playing */
cdaudiostop_do (); cdaudiostop_do ();
return 0; return 0;
} }
/* close device */ /* close device */
static void sys_cddev_close (void) static void sys_cddev_close (void)
{ {
cdaudiostop_do (); cdaudiostop_do ();
sys_command_close (DF_IOCTL, unitnum); sys_command_close (DF_IOCTL, unitnum);
} }
static int command_lengths[] = { 1,2,1,1,12,2,1,1,4,1,-1,-1,-1,-1,-1,-1 }; static int command_lengths[] = { 1,2,1,1,12,2,1,1,4,1,-1,-1,-1,-1,-1,-1 };
...@@ -741,8 +741,8 @@ static void cdrom_start_return_data (int len) ...@@ -741,8 +741,8 @@ static void cdrom_start_return_data (int len)
static void cdrom_return_data (void) static void cdrom_return_data (void)
{ {
uae_u32 cmd_buf = cdrx_address; uae_u32 cmd_buf = cdrx_address;
int i; int i;
uae_u8 checksum; uae_u8 checksum;
int len = cdrom_receive_started; int len = cdrom_receive_started;
if (!len) if (!len)
...@@ -752,14 +752,14 @@ static void cdrom_return_data (void) ...@@ -752,14 +752,14 @@ static void cdrom_return_data (void)
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("OUT:"); write_log ("OUT:");
#endif #endif
checksum = 0xff; checksum = 0xff;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
checksum -= cdrom_result_buffer[i]; checksum -= cdrom_result_buffer[i];
put_byte (cmd_buf + ((cdcomrxinx + i) & 0xff), cdrom_result_buffer[i]); put_byte (cmd_buf + ((cdcomrxinx + i) & 0xff), cdrom_result_buffer[i]);
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("%02X ", cdrom_result_buffer[i]); write_log ("%02X ", cdrom_result_buffer[i]);
#endif #endif
} }
put_byte (cmd_buf + ((cdcomrxinx + len) & 0xff), checksum); put_byte (cmd_buf + ((cdcomrxinx + len) & 0xff), checksum);
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("%02X\n", checksum); write_log ("%02X\n", checksum);
...@@ -781,7 +781,7 @@ static int cdrom_command_led (void) ...@@ -781,7 +781,7 @@ static int cdrom_command_led (void)
if (v & 0x80) { // result wanted? if (v & 0x80) { // result wanted?
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
cdrom_result_buffer[1] = cdrom_led & 1; cdrom_result_buffer[1] = cdrom_led & 1;
return 2; return 2;
} }
return 0; return 0;
} }
...@@ -789,7 +789,7 @@ static int cdrom_command_led (void) ...@@ -789,7 +789,7 @@ static int cdrom_command_led (void)
static int cdrom_command_media_status (void) static int cdrom_command_media_status (void)
{ {
cdrom_result_buffer[0] = 0x0a; cdrom_result_buffer[0] = 0x0a;
cdrom_result_buffer[1] = sys_command_ismedia (DF_IOCTL, unitnum, 0) ? 0x83: 0x80; cdrom_result_buffer[1] = sys_command_ismedia (DF_IOCTL, unitnum, 0) > 0 ? 0x83: 0x80;
return 2; return 2;
} }
...@@ -798,29 +798,29 @@ static int cdrom_command_status (void) ...@@ -798,29 +798,29 @@ static int cdrom_command_status (void)
{ {
cdrom_result_buffer[1] = 0x01; cdrom_result_buffer[1] = 0x01;
//cdrom_result_buffer[1] = 0x80; door open //cdrom_result_buffer[1] = 0x80; door open
if (unitnum >= 0) if (unitnum >= 0)
cdrom_toc (); cdrom_toc ();
/* firmware info */ /* firmware info */
memcpy (cdrom_result_buffer + 2, FIRMWAREVERSION, sizeof FIRMWAREVERSION); memcpy (cdrom_result_buffer + 2, FIRMWAREVERSION, sizeof FIRMWAREVERSION);
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
cd_initialized = 1; cd_initialized = 1;
return 20; return 20;
} }
/* return one TOC entry */ /* return one TOC entry */
static int cdrom_return_toc_entry (void) static int cdrom_return_toc_entry (void)
{ {
cdrom_result_buffer[0] = 6; cdrom_result_buffer[0] = 6;
if (cdrom_toc_entries == 0) { if (cdrom_toc_entries == 0) {
cdrom_result_buffer[1] = CDS_ERROR; cdrom_result_buffer[1] = CDS_ERROR;
return 15; return 15;
} }
cdrom_result_buffer[1] = 0; cdrom_result_buffer[1] = 0;
memcpy (cdrom_result_buffer + 2, cdrom_toc_buffer + cdrom_toc_counter * 13, 13); memcpy (cdrom_result_buffer + 2, cdrom_toc_buffer + cdrom_toc_counter * 13, 13);
cdrom_toc_counter++; cdrom_toc_counter++;
if (cdrom_toc_counter >= cdrom_toc_entries) if (cdrom_toc_counter >= cdrom_toc_entries)
cdrom_toc_counter = -1; cdrom_toc_counter = -1;
return 15; return 15;
} }
static int checkerr (void) static int checkerr (void)
{ {
...@@ -834,54 +834,54 @@ static int checkerr (void) ...@@ -834,54 +834,54 @@ static int checkerr (void)
/* pause CD audio */ /* pause CD audio */
static int cdrom_command_pause (void) static int cdrom_command_pause (void)
{ {
cdrom_toc_counter = -1; cdrom_toc_counter = -1;
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
if (checkerr ()) if (checkerr ())
return 2; return 2;
cdrom_result_buffer[1] = cdrom_playing ? CDS_PLAYING : 0; cdrom_result_buffer[1] = cdrom_playing ? CDS_PLAYING : 0;
if (!cdrom_playing) if (!cdrom_playing)
return 2; return 2;
if (cdrom_paused) if (cdrom_paused)
return 2; return 2;
cdrom_audiotimeout = 0; cdrom_audiotimeout = 0;
write_comm_pipe_u32 (&requests, 0x102, 1); write_comm_pipe_u32 (&requests, 0x102, 1);
cdrom_paused = 1; cdrom_paused = 1;
return 2; return 2;
} }
/* unpause CD audio */ /* unpause CD audio */
static int cdrom_command_unpause (void) static int cdrom_command_unpause (void)
{ {
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
if (checkerr ()) if (checkerr ())
return 2; return 2;
cdrom_result_buffer[1] = cdrom_playing ? CDS_PLAYING : 0; cdrom_result_buffer[1] = cdrom_playing ? CDS_PLAYING : 0;
if (!cdrom_paused) if (!cdrom_paused)
return 2; return 2;
if (!cdrom_playing) if (!cdrom_playing)
return 2; return 2;
cdrom_paused = 0; cdrom_paused = 0;
write_comm_pipe_u32 (&requests, 0x103, 1); write_comm_pipe_u32 (&requests, 0x103, 1);
return 2; return 2;
} }
/* seek head/play CD audio/read data sectors */ /* seek head/play CD audio/read data sectors */
static int cdrom_command_multi (void) static int cdrom_command_multi (void)
{ {
int seekpos = fromlongbcd (cdrom_command_buffer + 1); int seekpos = fromlongbcd (cdrom_command_buffer + 1);
int endpos = fromlongbcd (cdrom_command_buffer + 4); int endpos = fromlongbcd (cdrom_command_buffer + 4);
if (cdrom_playing) if (cdrom_playing)
cdaudiostop (); cdaudiostop ();
cdrom_speed = (cdrom_command_buffer[8] & 0x40) ? 2 : 1; cdrom_speed = (cdrom_command_buffer[8] & 0x40) ? 2 : 1;
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
cdrom_result_buffer[1] = 0; cdrom_result_buffer[1] = 0;
if (!cdrom_disk) { if (!cdrom_disk) {
cdrom_result_buffer[1] = 1; // no disk cdrom_result_buffer[1] = 1; // no disk
return 2; return 2;
} }
if (cdrom_command_buffer[7] == 0x80) { /* data read */ if (cdrom_command_buffer[7] == 0x80) { /* data read */
int cdrom_data_offset_end = msf2lsn (endpos); int cdrom_data_offset_end = msf2lsn (endpos);
cdrom_data_offset = msf2lsn (seekpos); cdrom_data_offset = msf2lsn (seekpos);
cdrom_seek_delay = abs (cdrom_current_sector - cdrom_data_offset); cdrom_seek_delay = abs (cdrom_current_sector - cdrom_data_offset);
...@@ -898,12 +898,12 @@ static int cdrom_command_multi (void) ...@@ -898,12 +898,12 @@ static int cdrom_command_multi (void)
seekpos, cdrom_data_offset, endpos, cdrom_data_offset_end, cdrom_speed, M68K_GETPC); seekpos, cdrom_data_offset, endpos, cdrom_data_offset_end, cdrom_speed, M68K_GETPC);
#endif #endif
cdrom_result_buffer[1] |= 0x02; cdrom_result_buffer[1] |= 0x02;
} else if (cdrom_command_buffer[10] & 4) { /* play audio */ } else if (cdrom_command_buffer[10] & 4) { /* play audio */
int scan = 0; int scan = 0;
if (cdrom_command_buffer[7] & 0x04) if (cdrom_command_buffer[7] & 0x04)
scan = 1; scan = 1;
else if (cdrom_command_buffer[7] & 0x08) else if (cdrom_command_buffer[7] & 0x08)
scan = -1; scan = -1;
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("PLAY FROM %06X (%d) to %06X (%d) SCAN=%d\n", write_log ("PLAY FROM %06X (%d) to %06X (%d) SCAN=%d\n",
seekpos, msf2lsn (seekpos), endpos, msf2lsn (endpos), scan); seekpos, msf2lsn (seekpos), endpos, msf2lsn (endpos), scan);
...@@ -919,40 +919,40 @@ static int cdrom_command_multi (void) ...@@ -919,40 +919,40 @@ static int cdrom_command_multi (void)
write_log ("SEEKTO %06X\n",seekpos); write_log ("SEEKTO %06X\n",seekpos);
#endif #endif
if (seekpos < 150) if (seekpos < 150)
cdrom_toc_counter = 0; cdrom_toc_counter = 0;
else else
cdrom_toc_counter = -1; cdrom_toc_counter = -1;
} }
return 2; return 2;
} }
/* return subq entry */ /* return subq entry */
static int cdrom_command_subq (void) static int cdrom_command_subq (void)
{ {
cdrom_result_buffer[0] = cdrom_command; cdrom_result_buffer[0] = cdrom_command;
cdrom_result_buffer[1] = 0; cdrom_result_buffer[1] = 0;
if (cd_qcode (cdrom_result_buffer + 2)) if (cd_qcode (cdrom_result_buffer + 2))
cdrom_result_buffer[1] = CDS_ERROR; cdrom_result_buffer[1] = CDS_ERROR;
return 15; return 15;
} }
static void cdrom_run_command (void) static void cdrom_run_command (void)
{ {
int i, cmd_len; int i, cmd_len;
uae_u8 checksum; uae_u8 checksum;
uae_u8 *pp = get_real_address (cdtx_address); uae_u8 *pp = get_real_address (cdtx_address);
if (!(cdrom_flags & CDFLAG_TXD)) if (!(cdrom_flags & CDFLAG_TXD))
return; return;
for (;;) { for (;;) {
if (cdrom_command_active) if (cdrom_command_active)
return; return;
if (cdcomtxinx == cdcomtxcmp) if (cdcomtxinx == cdcomtxcmp)
return; return;
cdrom_command = get_byte (cdtx_address + cdcomtxinx); cdrom_command = get_byte (cdtx_address + cdcomtxinx);
if ((cdrom_command & 0xf0) == 0) { if ((cdrom_command & 0xf0) == 0) {
cdcomtxinx = (cdcomtxinx + 1) & 0xff; cdcomtxinx = (cdcomtxinx + 1) & 0xff;
return; return;
} }
cdrom_checksum_error = 0; cdrom_checksum_error = 0;
cdrom_unknown_command = 0; cdrom_unknown_command = 0;
...@@ -975,16 +975,16 @@ static void cdrom_run_command (void) ...@@ -975,16 +975,16 @@ static void cdrom_run_command (void)
checksum = 0; checksum = 0;
for (i = 0; i < cmd_len + 1; i++) { for (i = 0; i < cmd_len + 1; i++) {
cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff)); cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff));
checksum += cdrom_command_buffer[i]; checksum += cdrom_command_buffer[i];
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("%02X ", cdrom_command_buffer[i]); write_log ("%02X ", cdrom_command_buffer[i]);
#endif #endif
} }
if (checksum!=0xff) { if (checksum != 0xff) {
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log (" checksum error"); write_log (" checksum error");
#endif #endif
cdrom_checksum_error = 1; cdrom_checksum_error = 1;
} }
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("\n"); write_log ("\n");
...@@ -993,16 +993,16 @@ static void cdrom_run_command (void) ...@@ -993,16 +993,16 @@ static void cdrom_run_command (void)
cdrom_command_length = cmd_len; cdrom_command_length = cmd_len;
set_status (CDINTERRUPT_TXDMADONE); set_status (CDINTERRUPT_TXDMADONE);
return; return;
} }
} }
static void cdrom_run_command_run (void) static void cdrom_run_command_run (void)
{ {
int len; int len;
cdcomtxinx = (cdcomtxinx + cdrom_command_length + 1) & 0xff; cdcomtxinx = (cdcomtxinx + cdrom_command_length + 1) & 0xff;
memset (cdrom_result_buffer, 0, sizeof(cdrom_result_buffer)); memset (cdrom_result_buffer, 0, sizeof (cdrom_result_buffer));
switch (cdrom_command & 0x0f) switch (cdrom_command & 0x0f)
{ {
case 2: case 2:
len = cdrom_command_pause (); len = cdrom_command_pause ();
...@@ -1040,8 +1040,8 @@ extern void encode_l2 (uae_u8 *p, int address); ...@@ -1040,8 +1040,8 @@ extern void encode_l2 (uae_u8 *p, int address);
static void cdrom_run_read (void) static void cdrom_run_read (void)
{ {
int i, sector, inc; int i, sector, inc;
int read = 0; int read = 0;
int sec; int sec;
static int seccnt; static int seccnt;
if (!(cdrom_flags & CDFLAG_ENABLE)) if (!(cdrom_flags & CDFLAG_ENABLE))
...@@ -1052,7 +1052,7 @@ static void cdrom_run_read (void) ...@@ -1052,7 +1052,7 @@ static void cdrom_run_read (void)
} }
if (!(cdrom_flags & CDFLAG_PBX)) if (!(cdrom_flags & CDFLAG_PBX))
return; return;
if (cdrom_data_offset<0) if (cdrom_data_offset < 0)
return; return;
if (unitnum < 0) if (unitnum < 0)
return; return;
...@@ -1066,7 +1066,7 @@ static void cdrom_run_read (void) ...@@ -1066,7 +1066,7 @@ static void cdrom_run_read (void)
sector = cdrom_current_sector = cdrom_data_offset + cdrom_sector_counter; sector = cdrom_current_sector = cdrom_data_offset + cdrom_sector_counter;
sec = sector - sector_buffer_sector_1; sec = sector - sector_buffer_sector_1;
if (sector_buffer_sector_1 >= 0 && sec >= 0 && sec < SECTOR_BUFFER_SIZE) { if (sector_buffer_sector_1 >= 0 && sec >= 0 && sec < SECTOR_BUFFER_SIZE) {
if (sector_buffer_info_1[sec] != 0xff && sector_buffer_info_1[sec] != 0) { if (sector_buffer_info_1[sec] != 0xff && sector_buffer_info_1[sec] != 0) {
uae_u8 buf[2352]; uae_u8 buf[2352];
memcpy (buf + 16, sector_buffer_1 + sec * 2048, 2048); memcpy (buf + 16, sector_buffer_1 + sec * 2048, 2048);
...@@ -1092,9 +1092,9 @@ static void cdrom_run_read (void) ...@@ -1092,9 +1092,9 @@ static void cdrom_run_read (void)
#endif #endif
} else { } else {
inc = 0; inc = 0;
} }
if (inc) if (inc)
cdrom_sector_counter++; cdrom_sector_counter++;
} }
static uae_sem_t akiko_sem; static uae_sem_t akiko_sem;
...@@ -1102,15 +1102,15 @@ static int lastmediastate = 0; ...@@ -1102,15 +1102,15 @@ static int lastmediastate = 0;
static void akiko_handler (void) static void akiko_handler (void)
{ {
if (unitnum < 0) if (unitnum < 0)
return; return;
if (!cd_initialized || cdrom_receive_started) if (!cd_initialized || cdrom_receive_started)
return; return;
#if 0 #if 0
if (cdrom_result_complete > cdcomrxcmp && cdrom_result_complete - cdcomrxcmp < 100) { if (cdrom_result_complete > cdcomrxcmp && cdrom_result_complete - cdcomrxcmp < 100) {
//set_status (CDINTERRUPT_RXDMADONE); //set_status (CDINTERRUPT_RXDMADONE);
return; return;
} }
if (cdcomrxcmp < cdrom_result_complete) if (cdcomrxcmp < cdrom_result_complete)
return; return;
#endif #endif
...@@ -1119,16 +1119,16 @@ static void akiko_handler (void) ...@@ -1119,16 +1119,16 @@ static void akiko_handler (void)
cdrom_start_return_data (cdrom_command_media_status ()); cdrom_start_return_data (cdrom_command_media_status ());
if (!lastmediastate) if (!lastmediastate)
cd_hunt = 1; cd_hunt = 1;
cdrom_toc (); cdrom_toc ();
/* do not remove! first try may fail */ /* do not remove! first try may fail */
cdrom_toc (); cdrom_toc ();
return; return;
} }
if (cdrom_toc_counter >= 0 && !cdrom_command_active && cdrom_dosomething) { if (cdrom_toc_counter >= 0 && !cdrom_command_active && cdrom_dosomething) {
cdrom_start_return_data (cdrom_return_toc_entry ()); cdrom_start_return_data (cdrom_return_toc_entry ());
cdrom_dosomething--; cdrom_dosomething--;
return; return;
} }
} }
static void akiko_internal (void) static void akiko_internal (void)
...@@ -1136,12 +1136,12 @@ static void akiko_internal (void) ...@@ -1136,12 +1136,12 @@ static void akiko_internal (void)
if (!currprefs.cs_cd32cd) if (!currprefs.cs_cd32cd)
return; return;
cdrom_return_data (); cdrom_return_data ();
cdrom_run_command (); cdrom_run_command ();
if (cdrom_command_active > 0) { if (cdrom_command_active > 0) {
cdrom_command_active--; cdrom_command_active--;
if (!cdrom_command_active) if (!cdrom_command_active)
cdrom_run_command_run (); cdrom_run_command_run ();
} }
} }
static void do_hunt (void) static void do_hunt (void)
...@@ -1151,8 +1151,16 @@ static void do_hunt (void) ...@@ -1151,8 +1151,16 @@ static void do_hunt (void)
if (sys_command_ismedia (DF_IOCTL, i, 1) > 0) if (sys_command_ismedia (DF_IOCTL, i, 1) > 0)
break; break;
} }
if (i == MAX_TOTAL_DEVICES) if (i == MAX_TOTAL_DEVICES) {
return; if (unitnum >= 0 && sys_command_ismedia (DF_IOCTL, unitnum, 1) >= 0)
return;
for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
if (sys_command_ismedia (DF_IOCTL, i, 1) >= 0)
break;
}
if (i == MAX_TOTAL_DEVICES)
return;
}
if (unitnum >= 0) { if (unitnum >= 0) {
int ou = unitnum; int ou = unitnum;
unitnum = -1; unitnum = -1;
...@@ -1169,10 +1177,10 @@ static void do_hunt (void) ...@@ -1169,10 +1177,10 @@ static void do_hunt (void)
void AKIKO_hsync_handler (void) void AKIKO_hsync_handler (void)
{ {
static int framecounter; static int framecounter;
if (!currprefs.cs_cd32cd) if (!currprefs.cs_cd32cd)
return; return;
if (cd_hunt) { if (cd_hunt) {
static int huntcnt; static int huntcnt;
...@@ -1183,8 +1191,8 @@ void AKIKO_hsync_handler (void) ...@@ -1183,8 +1191,8 @@ void AKIKO_hsync_handler (void)
huntcnt--; huntcnt--;
} }
framecounter--; framecounter--;
if (framecounter <= 0) { if (framecounter <= 0) {
int i; int i;
if (cdrom_led) { if (cdrom_led) {
if (cdrom_playing) if (cdrom_playing)
...@@ -1227,21 +1235,21 @@ void AKIKO_hsync_handler (void) ...@@ -1227,21 +1235,21 @@ void AKIKO_hsync_handler (void)
cdrom_start_return_data (2); cdrom_start_return_data (2);
} }
} }
} }
akiko_internal (); akiko_internal ();
akiko_handler (); akiko_handler ();
} }
/* cdrom data buffering thread */ /* cdrom data buffering thread */
static void *akiko_thread (void *null) static void *akiko_thread (void *null)
{ {
int i; int i;
uae_u8 *tmp1; uae_u8 *tmp1;
uae_u8 *tmp2; uae_u8 *tmp2;
int tmp3; int tmp3;
uae_u8 *p; uae_u8 *p;
int offset; int offset;
int sector; int sector;
while (akiko_thread_running || comm_pipe_has_data (&requests)) { while (akiko_thread_running || comm_pipe_has_data (&requests)) {
...@@ -1289,10 +1297,16 @@ static void *akiko_thread (void *null) ...@@ -1289,10 +1297,16 @@ static void *akiko_thread (void *null)
} }
if (mediacheckcounter <= 0) { if (mediacheckcounter <= 0) {
int media = sys_command_ismedia (DF_IOCTL, unitnum, 1);
mediacheckcounter = 312 * 50 * 2; mediacheckcounter = 312 * 50 * 2;
if (media != lastmediastate) { int media = sys_command_ismedia (DF_IOCTL, unitnum, 1);
write_log ("media changed = %d\n", media); if (media < 0) {
cd_hunt = 1;
write_log ("CD32: device unit %d lost\n", unitnum);
media = lastmediastate = cdrom_disk = 0;
mediachanged = 1;
cdaudiostop_do ();
} else if (media != lastmediastate) {
write_log ("CD32: media changed = %d (hunt=%d)\n", media, cd_hunt);
lastmediastate = cdrom_disk = media; lastmediastate = cdrom_disk = media;
mediachanged = 1; mediachanged = 1;
cdaudiostop_do (); cdaudiostop_do ();
...@@ -1307,7 +1321,7 @@ static void *akiko_thread (void *null) ...@@ -1307,7 +1321,7 @@ static void *akiko_thread (void *null)
} }
if (cdrom_data_end > 0 && sector >= 0 && if (cdrom_data_end > 0 && sector >= 0 &&
(sector_buffer_sector_1 < 0 || sector < sector_buffer_sector_1 || sector >= sector_buffer_sector_1 + SECTOR_BUFFER_SIZE * 2 / 3 || i != SECTOR_BUFFER_SIZE)) { (sector_buffer_sector_1 < 0 || sector < sector_buffer_sector_1 || sector >= sector_buffer_sector_1 + SECTOR_BUFFER_SIZE * 2 / 3 || i != SECTOR_BUFFER_SIZE)) {
memset (sector_buffer_info_2, 0, SECTOR_BUFFER_SIZE); memset (sector_buffer_info_2, 0, SECTOR_BUFFER_SIZE);
#if AKIKO_DEBUG_IO_CMD #if AKIKO_DEBUG_IO_CMD
write_log ("filling buffer sector=%d (max=%d)\n", sector, cdrom_data_end); write_log ("filling buffer sector=%d (max=%d)\n", sector, cdrom_data_end);
#endif #endif
...@@ -1335,20 +1349,20 @@ static void *akiko_thread (void *null) ...@@ -1335,20 +1349,20 @@ static void *akiko_thread (void *null)
} }
uae_sem_post (&akiko_sem); uae_sem_post (&akiko_sem);
uae_msleep (10); uae_msleep (10);
} }
akiko_thread_running = -1; akiko_thread_running = -1;
return 0; return 0;
} }
STATIC_INLINE uae_u8 akiko_get_long (uae_u32 v, int offset) STATIC_INLINE uae_u8 akiko_get_long (uae_u32 v, int offset)
{ {
return v >> ((3 - offset) * 8); return v >> ((3 - offset) * 8);
} }
STATIC_INLINE void akiko_put_long (uae_u32 *p, int offset, int v) STATIC_INLINE void akiko_put_long (uae_u32 *p, int offset, int v)
{ {
*p &= ~(0xff << ((3 - offset) * 8)); *p &= ~(0xff << ((3 - offset) * 8));
*p |= v << ((3 - offset) * 8); *p |= v << ((3 - offset) * 8);
} }
static uae_u32 REGPARAM3 akiko_lget (uaecptr) REGPARAM; static uae_u32 REGPARAM3 akiko_lget (uaecptr) REGPARAM;
...@@ -1364,7 +1378,7 @@ static uae_u32 akiko_bget2 (uaecptr addr, int msg) ...@@ -1364,7 +1378,7 @@ static uae_u32 akiko_bget2 (uaecptr addr, int msg)
{ {
uae_u8 v = 0; uae_u8 v = 0;
addr &= 0xffff; addr &= 0xffff;
switch (addr) switch (addr)
{ {
...@@ -1463,52 +1477,52 @@ static uae_u32 REGPARAM2 akiko_bget (uaecptr addr) ...@@ -1463,52 +1477,52 @@ static uae_u32 REGPARAM2 akiko_bget (uaecptr addr)
#ifdef JIT #ifdef JIT
special_mem |= S_READ; special_mem |= S_READ;
#endif #endif
return akiko_bget2 (addr, 1); return akiko_bget2 (addr, 1);
} }
static uae_u32 REGPARAM2 akiko_wget (uaecptr addr) static uae_u32 REGPARAM2 akiko_wget (uaecptr addr)
{ {
uae_u16 v; uae_u16 v;
#ifdef JIT #ifdef JIT
special_mem |= S_READ; special_mem |= S_READ;
#endif #endif
addr &= 0xffff; addr &= 0xffff;
v = akiko_bget2 (addr + 1, 0); v = akiko_bget2 (addr + 1, 0);
v |= akiko_bget2 (addr + 0, 0) << 8; v |= akiko_bget2 (addr + 0, 0) << 8;
if (addr < 0x30 && AKIKO_DEBUG_IO) if (addr < 0x30 && AKIKO_DEBUG_IO)
write_log ("akiko_wget %08X: %08X %04X\n", M68K_GETPC, addr, v & 0xffff); write_log ("akiko_wget %08X: %08X %04X\n", M68K_GETPC, addr, v & 0xffff);
return v; return v;
} }
uae_u32 REGPARAM2 akiko_lget (uaecptr addr) uae_u32 REGPARAM2 akiko_lget (uaecptr addr)
{ {
uae_u32 v; uae_u32 v;
#ifdef JIT #ifdef JIT
special_mem |= S_READ; special_mem |= S_READ;
#endif #endif
addr &= 0xffff; addr &= 0xffff;
v = akiko_bget2 (addr + 3, 0); v = akiko_bget2 (addr + 3, 0);
v |= akiko_bget2 (addr + 2, 0) << 8; v |= akiko_bget2 (addr + 2, 0) << 8;
v |= akiko_bget2 (addr + 1, 0) << 16; v |= akiko_bget2 (addr + 1, 0) << 16;
v |= akiko_bget2 (addr + 0, 0) << 24; v |= akiko_bget2 (addr + 0, 0) << 24;
if (addr < 0x30 && (addr != 4 && addr != 8) && AKIKO_DEBUG_IO) if (addr < 0x30 && (addr != 4 && addr != 8) && AKIKO_DEBUG_IO)
write_log ("akiko_lget %08X: %08X %08X\n", M68K_GETPC, addr, v); write_log ("akiko_lget %08X: %08X %08X\n", M68K_GETPC, addr, v);
return v; return v;
} }
STATIC_INLINE void REGPARAM2 akiko_bput2 (uaecptr addr, uae_u32 v, int msg) STATIC_INLINE void REGPARAM2 akiko_bput2 (uaecptr addr, uae_u32 v, int msg)
{ {
uae_u32 tmp; uae_u32 tmp;
addr &= 0xffff; addr &= 0xffff;
v &= 0xff; v &= 0xff;
if(msg && addr < 0x30 && AKIKO_DEBUG_IO) if(msg && addr < 0x30 && AKIKO_DEBUG_IO)
write_log ("akiko_bput %08X: %08X=%02X\n", M68K_GETPC, addr, v & 0xff); write_log ("akiko_bput %08X: %08X=%02X\n", M68K_GETPC, addr, v & 0xff);
switch (addr) switch (addr)
{ {
case 0x30: case 0x30:
case 0x31: case 0x31:
case 0x32: case 0x32:
...@@ -1597,8 +1611,8 @@ STATIC_INLINE void REGPARAM2 akiko_bput2 (uaecptr addr, uae_u32 v, int msg) ...@@ -1597,8 +1611,8 @@ STATIC_INLINE void REGPARAM2 akiko_bput2 (uaecptr addr, uae_u32 v, int msg)
default: default:
write_log ("akiko_bput: unknown address %08X=%02X PC=%08X\n", addr, v & 0xff, M68K_GETPC); write_log ("akiko_bput: unknown address %08X=%02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
break; break;
} }
akiko_internal (); akiko_internal ();
uae_sem_post (&akiko_sem); uae_sem_post (&akiko_sem);
} }
...@@ -1607,7 +1621,7 @@ static void REGPARAM2 akiko_bput (uaecptr addr, uae_u32 v) ...@@ -1607,7 +1621,7 @@ static void REGPARAM2 akiko_bput (uaecptr addr, uae_u32 v)
#ifdef JIT #ifdef JIT
special_mem |= S_WRITE; special_mem |= S_WRITE;
#endif #endif
akiko_bput2 (addr, v, 1); akiko_bput2 (addr, v, 1);
} }
void REGPARAM2 akiko_wput (uaecptr addr, uae_u32 v) void REGPARAM2 akiko_wput (uaecptr addr, uae_u32 v)
...@@ -1615,11 +1629,11 @@ void REGPARAM2 akiko_wput (uaecptr addr, uae_u32 v) ...@@ -1615,11 +1629,11 @@ void REGPARAM2 akiko_wput (uaecptr addr, uae_u32 v)
#ifdef JIT #ifdef JIT
special_mem |= S_WRITE; special_mem |= S_WRITE;
#endif #endif
addr &= 0xfff; addr &= 0xfff;
if((addr < 0x30 && AKIKO_DEBUG_IO)) if((addr < 0x30 && AKIKO_DEBUG_IO))
write_log ("akiko_wput %08X: %08X=%04X\n", M68K_GETPC, addr, v & 0xffff); write_log ("akiko_wput %08X: %08X=%04X\n", M68K_GETPC, addr, v & 0xffff);
akiko_bput2 (addr + 1, v & 0xff, 0); akiko_bput2 (addr + 1, v & 0xff, 0);
akiko_bput2 (addr + 0, v >> 8, 0); akiko_bput2 (addr + 0, v >> 8, 0);
} }
void REGPARAM2 akiko_lput (uaecptr addr, uae_u32 v) void REGPARAM2 akiko_lput (uaecptr addr, uae_u32 v)
...@@ -1627,13 +1641,13 @@ void REGPARAM2 akiko_lput (uaecptr addr, uae_u32 v) ...@@ -1627,13 +1641,13 @@ void REGPARAM2 akiko_lput (uaecptr addr, uae_u32 v)
#ifdef JIT #ifdef JIT
special_mem |= S_WRITE; special_mem |= S_WRITE;
#endif #endif
addr &= 0xffff; addr &= 0xffff;
if(addr < 0x30 && AKIKO_DEBUG_IO) if(addr < 0x30 && AKIKO_DEBUG_IO)
write_log ("akiko_lput %08X: %08X=%08X\n", M68K_GETPC, addr, v); write_log ("akiko_lput %08X: %08X=%08X\n", M68K_GETPC, addr, v);
akiko_bput2 (addr + 3, (v >> 0) & 0xff, 0); akiko_bput2 (addr + 3, (v >> 0) & 0xff, 0);
akiko_bput2 (addr + 2, (v >> 8) & 0xff, 0); akiko_bput2 (addr + 2, (v >> 8) & 0xff, 0);
akiko_bput2 (addr + 1, (v >> 16) & 0xff, 0); akiko_bput2 (addr + 1, (v >> 16) & 0xff, 0);
akiko_bput2 (addr + 0, (v >> 24) & 0xff, 0); akiko_bput2 (addr + 0, (v >> 24) & 0xff, 0);
} }
addrbank akiko_bank = { addrbank akiko_bank = {
...@@ -1646,7 +1660,7 @@ addrbank akiko_bank = { ...@@ -1646,7 +1660,7 @@ addrbank akiko_bank = {
static void akiko_cdrom_free (void) static void akiko_cdrom_free (void)
{ {
if (unitnum >= 0) if (unitnum >= 0)
sys_cddev_close (); sys_cddev_close ();
unitnum = -1; unitnum = -1;
xfree (sector_buffer_1); xfree (sector_buffer_1);
xfree (sector_buffer_2); xfree (sector_buffer_2);
...@@ -1657,7 +1671,7 @@ static void akiko_cdrom_free (void) ...@@ -1657,7 +1671,7 @@ static void akiko_cdrom_free (void)
sector_buffer_info_1 = 0; sector_buffer_info_1 = 0;
sector_buffer_info_2 = 0; sector_buffer_info_2 = 0;
cdromok = 0; cdromok = 0;
} }
void akiko_reset (void) void akiko_reset (void)
{ {
...@@ -1691,7 +1705,7 @@ void akiko_reset (void) ...@@ -1691,7 +1705,7 @@ void akiko_reset (void)
void akiko_free (void) void akiko_free (void)
{ {
akiko_reset (); akiko_reset ();
akiko_cdrom_free (); akiko_cdrom_free ();
} }
...@@ -1701,77 +1715,77 @@ int akiko_init (void) ...@@ -1701,77 +1715,77 @@ int akiko_init (void)
unitnum = -1; unitnum = -1;
if (!device_func_init(DEVICE_TYPE_ANY)) { if (!device_func_init(DEVICE_TYPE_ANY)) {
write_log ("no CDROM support\n"); write_log ("no CDROM support\n");
return 0; return 0;
} }
if (!sys_cddev_open ()) { if (!sys_cddev_open ()) {
cdromok = 1; cdromok = 1;
sector_buffer_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048); sector_buffer_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048);
sector_buffer_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048); sector_buffer_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048);
sector_buffer_info_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE); sector_buffer_info_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE);
sector_buffer_info_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE); sector_buffer_info_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE);
sector_buffer_sector_1 = -1; sector_buffer_sector_1 = -1;
sector_buffer_sector_2 = -1; sector_buffer_sector_2 = -1;
}
} }
}
uae_sem_init (&akiko_sem, 0, 1); uae_sem_init (&akiko_sem, 0, 1);
if (!savestate_state) { if (!savestate_state) {
cdrom_playing = cdrom_paused = 0; cdrom_playing = cdrom_paused = 0;
cdrom_data_offset = -1; cdrom_data_offset = -1;
} }
if (cdromok && !akiko_thread_running) { if (cdromok && !akiko_thread_running) {
akiko_thread_running = 1; akiko_thread_running = 1;
init_comm_pipe (&requests, 100, 1); init_comm_pipe (&requests, 100, 1);
uae_start_thread ("akiko", akiko_thread, 0, NULL); uae_start_thread ("akiko", akiko_thread, 0, NULL);
} }
return 1; return 1;
} }
#ifdef SAVESTATE #ifdef SAVESTATE
uae_u8 *save_akiko(int *len) uae_u8 *save_akiko(int *len)
{ {
uae_u8 *dstbak, *dst; uae_u8 *dstbak, *dst;
int i; int i;
if (!currprefs.cs_cd32cd) if (!currprefs.cs_cd32cd)
return NULL; return NULL;
dstbak = dst = xmalloc (uae_u8, 1000); dstbak = dst = xmalloc (uae_u8, 1000);
save_u16 (0); save_u16 (0);
save_u16 (0xCAFE); save_u16 (0xCAFE);
save_u32 (cdrom_intreq); save_u32 (cdrom_intreq);
save_u32 (cdrom_intena); save_u32 (cdrom_intena);
save_u32 (0); save_u32 (0);
save_u32 (cdrom_addressdata); save_u32 (cdrom_addressdata);
save_u32 (cdrom_addressmisc); save_u32 (cdrom_addressmisc);
save_u8 (cdrom_subcodeoffset); save_u8 (cdrom_subcodeoffset);
save_u8 (cdcomrxinx); save_u8 (cdcomrxinx);
save_u8 (cdcomrxinx); save_u8 (cdcomrxinx);
save_u8 (0); save_u8 (0);
save_u8 (0); save_u8 (0);
save_u8 (cdcomtxcmp); save_u8 (cdcomtxcmp);
save_u8 (0); save_u8 (0);
save_u8 (0); save_u8 (0);
save_u16 ((uae_u16)cdrom_pbx); save_u16 ((uae_u16)cdrom_pbx);
save_u16 (0); save_u16 (0);
save_u32 (cdrom_flags); save_u32 (cdrom_flags);
save_u32 (0); save_u32 (0);
save_u32 (0); save_u32 (0);
save_u32 ((scl_dir ? 0x8000 : 0) | (sda_dir ? 0x4000 : 0)); save_u32 ((scl_dir ? 0x8000 : 0) | (sda_dir ? 0x4000 : 0));
save_u32 (0); save_u32 (0);
save_u32 (0); save_u32 (0);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
save_u32 (akiko_buffer[i]); save_u32 (akiko_buffer[i]);
save_u8 ((uae_u8)akiko_read_offset); save_u8 ((uae_u8)akiko_read_offset);
save_u8 ((uae_u8)akiko_write_offset); save_u8 ((uae_u8)akiko_write_offset);
save_u32 ((cdrom_playing ? 1 : 0) | (cdrom_paused ? 2 : 0) | (cdrom_disk ? 4 : 0)); save_u32 ((cdrom_playing ? 1 : 0) | (cdrom_paused ? 2 : 0) | (cdrom_disk ? 4 : 0));
if (cdrom_playing) if (cdrom_playing)
cd_qcode (0); cd_qcode (0);
save_u32 (last_play_pos); save_u32 (last_play_pos);
save_u32 (last_play_end); save_u32 (last_play_end);
save_u8 ((uae_u8)cdrom_toc_counter); save_u8 ((uae_u8)cdrom_toc_counter);
save_u8 (cdrom_speed); save_u8 (cdrom_speed);
save_u8 (cdrom_current_sector); save_u8 (cdrom_current_sector);
...@@ -1780,13 +1794,13 @@ uae_u8 *save_akiko(int *len) ...@@ -1780,13 +1794,13 @@ uae_u8 *save_akiko(int *len)
save_u8 (cdrom_toc_entries); save_u8 (cdrom_toc_entries);
save_u32 (cdrom_leadout); save_u32 (cdrom_leadout);
*len = dst - dstbak; *len = dst - dstbak;
return dstbak; return dstbak;
} }
uae_u8 *restore_akiko (uae_u8 *src) uae_u8 *restore_akiko (uae_u8 *src)
{ {
uae_u32 v; uae_u32 v;
int i; int i;
if (!currprefs.cs_cd32cd || !cdromok) { if (!currprefs.cs_cd32cd || !cdromok) {
...@@ -1795,11 +1809,11 @@ uae_u8 *restore_akiko (uae_u8 *src) ...@@ -1795,11 +1809,11 @@ uae_u8 *restore_akiko (uae_u8 *src)
akiko_init (); akiko_init ();
} }
restore_u16 (); restore_u16 ();
restore_u16 (); restore_u16 ();
cdrom_intreq = restore_u32 (); cdrom_intreq = restore_u32 ();
cdrom_intena = restore_u32 (); cdrom_intena = restore_u32 ();
restore_u32 (); restore_u32 ();
cdrom_addressdata = restore_u32 (); cdrom_addressdata = restore_u32 ();
cdrom_addressmisc = restore_u32 (); cdrom_addressmisc = restore_u32 ();
subcode_address = cdrom_addressmisc | 0x100; subcode_address = cdrom_addressmisc | 0x100;
...@@ -1808,36 +1822,36 @@ uae_u8 *restore_akiko (uae_u8 *src) ...@@ -1808,36 +1822,36 @@ uae_u8 *restore_akiko (uae_u8 *src)
cdrom_subcodeoffset = restore_u8 (); cdrom_subcodeoffset = restore_u8 ();
cdcomtxinx = restore_u8 (); cdcomtxinx = restore_u8 ();
cdcomrxinx = restore_u8 (); cdcomrxinx = restore_u8 ();
restore_u8 (); restore_u8 ();
restore_u8 (); restore_u8 ();
cdcomtxcmp = restore_u8 (); cdcomtxcmp = restore_u8 ();
restore_u8 (); restore_u8 ();
restore_u8 (); restore_u8 ();
cdrom_pbx = restore_u16 (); cdrom_pbx = restore_u16 ();
restore_u16 (); restore_u16 ();
cdrom_flags = restore_u32 (); cdrom_flags = restore_u32 ();
restore_u32 (); restore_u32 ();
restore_u32 (); restore_u32 ();
v = restore_u32 (); v = restore_u32 ();
scl_dir = (v & 0x8000) ? 1 : 0; scl_dir = (v & 0x8000) ? 1 : 0;
sda_dir = (v & 0x4000) ? 1 : 0; sda_dir = (v & 0x4000) ? 1 : 0;
restore_u32 (); restore_u32 ();
restore_u32 (); restore_u32 ();
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
akiko_buffer[i] = restore_u32 (); akiko_buffer[i] = restore_u32 ();
akiko_read_offset = restore_u8 (); akiko_read_offset = restore_u8 ();
akiko_write_offset = restore_u8 (); akiko_write_offset = restore_u8 ();
cdrom_playing = cdrom_paused = 0; cdrom_playing = cdrom_paused = 0;
v = restore_u32 (); v = restore_u32 ();
if (v & 1) if (v & 1)
cdrom_playing = 1; cdrom_playing = 1;
if (v & 2) if (v & 2)
cdrom_paused = 1; cdrom_paused = 1;
last_play_pos = restore_u32 (); last_play_pos = restore_u32 ();
last_play_end = restore_u32 (); last_play_end = restore_u32 ();
cdrom_toc_counter = (uae_s8)restore_u8 (); cdrom_toc_counter = (uae_s8)restore_u8 ();
cdrom_speed = restore_u8 (); cdrom_speed = restore_u8 ();
cdrom_current_sector = (uae_s8)restore_u8 (); cdrom_current_sector = (uae_s8)restore_u8 ();
...@@ -1846,7 +1860,7 @@ uae_u8 *restore_akiko (uae_u8 *src) ...@@ -1846,7 +1860,7 @@ uae_u8 *restore_akiko (uae_u8 *src)
restore_u8 (); restore_u8 ();
restore_u32 (); restore_u32 ();
return src; return src;
} }
void restore_akiko_finish (void) void restore_akiko_finish (void)
...@@ -1870,12 +1884,12 @@ void restore_akiko_finish (void) ...@@ -1870,12 +1884,12 @@ void restore_akiko_finish (void)
void akiko_entergui (void) void akiko_entergui (void)
{ {
if (cdrom_playing) if (cdrom_playing)
write_comm_pipe_u32 (&requests, 0x0102, 1); write_comm_pipe_u32 (&requests, 0x0102, 1);
} }
void akiko_exitgui (void) void akiko_exitgui (void)
{ {
if (cdrom_playing) if (cdrom_playing)
write_comm_pipe_u32 (&requests, 0x0103, 1); write_comm_pipe_u32 (&requests, 0x0103, 1);
} }
......
/* /*
* UAE - The Un*x Amiga Emulator * UAE - The Un*x Amiga Emulator
* *
* lowlevel device glue * lowlevel device glue
* *
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
struct device_functions *device_func[2]; struct device_functions *device_func[2];
static int have_ioctl; static int have_ioctl;
static int openlist[MAX_TOTAL_DEVICES];
static int forcedunit = -1;
#ifdef _WIN32 #ifdef _WIN32
...@@ -85,26 +87,40 @@ static void install_driver (int flags) ...@@ -85,26 +87,40 @@ static void install_driver (int flags)
# endif # endif
#endif #endif
int sys_command_isopen (int unitnum)
{
return openlist[unitnum];
}
void sys_command_setunit (int unitnum)
{
forcedunit = unitnum;
}
int sys_command_open (int mode, int unitnum) int sys_command_open (int mode, int unitnum)
{ {
int ret = 0;
if (mode == DF_SCSI || !have_ioctl) { if (mode == DF_SCSI || !have_ioctl) {
if (device_func[DF_SCSI] == NULL) if (device_func[DF_SCSI] != NULL)
return 0; ret = device_func[DF_SCSI]->opendev (unitnum);
return device_func[DF_SCSI]->opendev (unitnum);
} else { } else {
return device_func[DF_IOCTL]->opendev (unitnum); ret = device_func[DF_IOCTL]->opendev (unitnum);
} }
if (ret)
openlist[unitnum]++;
return ret;
} }
void sys_command_close (int mode, int unitnum) void sys_command_close (int mode, int unitnum)
{ {
if (mode == DF_SCSI || !have_ioctl) { if (mode == DF_SCSI || !have_ioctl) {
if (device_func[DF_SCSI] == NULL) if (device_func[DF_SCSI] != NULL)
return; device_func[DF_SCSI]->closedev (unitnum);
device_func[DF_SCSI]->closedev (unitnum);
} else { } else {
device_func[DF_IOCTL]->closedev (unitnum); device_func[DF_IOCTL]->closedev (unitnum);
} }
if (openlist[unitnum] > 0)
openlist[unitnum]--;
} }
void device_func_reset (void) void device_func_reset (void)
...@@ -117,6 +133,7 @@ int device_func_init (int flags) ...@@ -117,6 +133,7 @@ int device_func_init (int flags)
int support_scsi = 0, support_ioctl = 0; int support_scsi = 0, support_ioctl = 0;
int oflags = (flags & DEVICE_TYPE_SCSI) ? 0 : (1 << INQ_ROMD); int oflags = (flags & DEVICE_TYPE_SCSI) ? 0 : (1 << INQ_ROMD);
forcedunit = -1;
install_driver (flags); install_driver (flags);
if (device_func[DF_IOCTL]) if (device_func[DF_IOCTL])
have_ioctl = 1; have_ioctl = 1;
...@@ -286,6 +303,11 @@ int sys_command_ismedia (int mode, int unitnum, int quick) ...@@ -286,6 +303,11 @@ int sys_command_ismedia (int mode, int unitnum, int quick)
{ {
struct device_info di; struct device_info di;
if (forcedunit >= 0) {
if (unitnum != forcedunit)
return -1;
}
if (mode == DF_SCSI || !have_ioctl || !device_func[DF_IOCTL]->ismedia) { if (mode == DF_SCSI || !have_ioctl || !device_func[DF_IOCTL]->ismedia) {
if (quick) if (quick)
return -1; return -1;
......
...@@ -369,7 +369,7 @@ static int cdrom_info (uae_u8 *out) ...@@ -369,7 +369,7 @@ static int cdrom_info (uae_u8 *out)
uae_u32 size; uae_u32 size;
int i; int i;
if (!ismedia ()) if (ismedia () <= 0)
return -1; return -1;
cd_motor = 1; cd_motor = 1;
out[0] = cdrom_toc[2]; out[0] = cdrom_toc[2];
...@@ -392,7 +392,7 @@ static int read_toc (int track, int msflsn, uae_u8 *out) ...@@ -392,7 +392,7 @@ static int read_toc (int track, int msflsn, uae_u8 *out)
uae_u8 *buf = cdrom_toc, *s; uae_u8 *buf = cdrom_toc, *s;
int i, j; int i, j;
if (!ismedia ()) if (ismedia () <= 0)
return -1; return -1;
if (!out) if (!out)
return 0; return 0;
...@@ -615,10 +615,10 @@ static uae_u8 *read_raw (int sector, int size) ...@@ -615,10 +615,10 @@ static uae_u8 *read_raw (int sector, int size)
_stprintf (fname, "track%d.bin", trackcnt); _stprintf (fname, "track%d.bin", trackcnt);
zfile_fclose (f); zfile_fclose (f);
f = zfile_fopen (fname, "rb", ZFD_NORMAL); f = zfile_fopen (fname, "rb", ZFD_NORMAL);
if (!f) if (f)
write_log ("failed to open '%s'\n", fname);
else
write_log ("opened '%s'\n", fname); write_log ("opened '%s'\n", fname);
else
write_log ("failed to open '%s'\n", fname);
track = trackcnt; track = trackcnt;
} }
if (f) { if (f) {
...@@ -692,8 +692,14 @@ static void *dev_thread (void *p) ...@@ -692,8 +692,14 @@ static void *dev_thread (void *p)
break; break;
case 0x0101: case 0x0101:
{ {
if (ismedia () != cd_media) { int m = ismedia ();
cd_media = ismedia (); if (m < 0) {
write_log ("CDTV: device lost\n");
activate_stch = 1;
cd_hunt = 1;
cd_media = 0;
} else if (m != cd_media) {
cd_media = m;
get_toc (); get_toc ();
activate_stch = 1; activate_stch = 1;
if (cd_playing) if (cd_playing)
...@@ -887,8 +893,16 @@ static void do_hunt (void) ...@@ -887,8 +893,16 @@ static void do_hunt (void)
if (sys_command_ismedia (DF_IOCTL, i, 1) > 0) if (sys_command_ismedia (DF_IOCTL, i, 1) > 0)
break; break;
} }
if (i == MAX_TOTAL_DEVICES) if (i == MAX_TOTAL_DEVICES) {
return; if (unitnum >= 0 && sys_command_ismedia (DF_IOCTL, unitnum, 1) >= 0)
return;
for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
if (sys_command_ismedia (DF_IOCTL, i, 1) >= 0)
break;
}
if (i == MAX_TOTAL_DEVICES)
return;
}
if (unitnum >= 0) { if (unitnum >= 0) {
cdaudiostop (); cdaudiostop ();
sys_command_close (DF_IOCTL, unitnum); sys_command_close (DF_IOCTL, unitnum);
......
...@@ -1414,6 +1414,10 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) ...@@ -1414,6 +1414,10 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
} }
#ifdef GFXFILTER #ifdef GFXFILTER
if (_tcscmp (option, "gfx_filter_overlay") == 0) {
return 1;
}
if (_tcscmp (option, "gfx_filter") == 0) { if (_tcscmp (option, "gfx_filter") == 0) {
int i = 0; int i = 0;
TCHAR *s = _tcschr (value, ':'); TCHAR *s = _tcschr (value, ':');
......
...@@ -3769,9 +3769,10 @@ static void ...@@ -3769,9 +3769,10 @@ static void
possible_loadseg(); possible_loadseg();
} }
#endif #endif
if (valid_address (addr, size)) { if (size == 0) {
uae_u8 *realpt; actual = 0;
realpt = get_real_address (addr); } else if (valid_address (addr, size)) {
uae_u8 *realpt = get_real_address (addr);
actual = fs_read (k->fd, realpt, size); actual = fs_read (k->fd, realpt, size);
if (actual == 0) { if (actual == 0) {
...@@ -3826,8 +3827,8 @@ static void ...@@ -3826,8 +3827,8 @@ static void
{ {
Key *k = lookup_key (unit, GET_PCK_ARG1 (packet)); Key *k = lookup_key (unit, GET_PCK_ARG1 (packet));
uaecptr addr = GET_PCK_ARG2 (packet); uaecptr addr = GET_PCK_ARG2 (packet);
long size = GET_PCK_ARG3 (packet); uae_u32 size = GET_PCK_ARG3 (packet);
long actual; uae_u32 actual;
uae_u8 *buf; uae_u8 *buf;
int i; int i;
...@@ -3846,12 +3847,12 @@ static void ...@@ -3846,12 +3847,12 @@ static void
return; return;
} }
if (valid_address (addr, size)) { if (size == 0) {
actual = 0;
} else if (valid_address (addr, size)) {
uae_u8 *realpt = get_real_address (addr); uae_u8 *realpt = get_real_address (addr);
actual = fs_write (k->fd, realpt, size); actual = fs_write (k->fd, realpt, size);
} else { } else {
write_log ("unixfs warning: Bad pointer passed for write: %08x, size %d\n", addr, size); write_log ("unixfs warning: Bad pointer passed for write: %08x, size %d\n", addr, size);
/* ugh this is inefficient but easy */ /* ugh this is inefficient but easy */
buf = xmalloc (uae_u8, size); buf = xmalloc (uae_u8, size);
......
...@@ -121,6 +121,8 @@ extern int device_func_init(int flags); ...@@ -121,6 +121,8 @@ extern int device_func_init(int flags);
extern void device_func_reset(void); extern void device_func_reset(void);
extern int sys_command_open (int mode, int unitnum); extern int sys_command_open (int mode, int unitnum);
extern void sys_command_close (int mode, int unitnum); extern void sys_command_close (int mode, int unitnum);
extern int sys_command_isopen (int unitnum);
extern void sys_command_setunit (int unitnum);
extern struct device_info *sys_command_info (int mode, int unitnum, struct device_info *di); extern struct device_info *sys_command_info (int mode, int unitnum, struct device_info *di);
extern struct device_scsi_info *sys_command_scsi_info (int mode, int unitnum, struct device_scsi_info *di); extern struct device_scsi_info *sys_command_scsi_info (int mode, int unitnum, struct device_scsi_info *di);
extern void sys_command_cd_pause (int mode, int unitnum, int paused); extern void sys_command_cd_pause (int mode, int unitnum, int paused);
......
...@@ -14,10 +14,10 @@ STATIC_INLINE double to_single (uae_u32 value) ...@@ -14,10 +14,10 @@ STATIC_INLINE double to_single (uae_u32 value)
double frac; double frac;
if ((value & 0x7fffffff) == 0) if ((value & 0x7fffffff) == 0)
return (0.0); return (0.0);
frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0; frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0;
if (value & 0x80000000) if (value & 0x80000000)
frac = -frac; frac = -frac;
return (ldexp (frac, ((value >> 23) & 0xff) - 127)); return (ldexp (frac, ((value >> 23) & 0xff) - 127));
} }
#endif #endif
...@@ -30,18 +30,18 @@ STATIC_INLINE uae_u32 from_single (double src) ...@@ -30,18 +30,18 @@ STATIC_INLINE uae_u32 from_single (double src)
double frac; double frac;
if (src == 0.0) if (src == 0.0)
return 0; return 0;
if (src < 0) { if (src < 0) {
tmp = 0x80000000; tmp = 0x80000000;
src = -src; src = -src;
} else { } else {
tmp = 0; tmp = 0;
} }
frac = frexp (src, &expon); frac = frexp (src, &expon);
frac += 0.5 / 16777216.0; frac += 0.5 / 16777216.0;
if (frac >= 1.0) { if (frac >= 1.0) {
frac /= 2.0; frac /= 2.0;
expon++; expon++;
} }
return (tmp | (((expon + 127 - 1) & 0xff) << 23) | return (tmp | (((expon + 127 - 1) & 0xff) << 23) |
(((int) (frac * 16777216.0)) & 0x7fffff)); (((int) (frac * 16777216.0)) & 0x7fffff));
...@@ -54,11 +54,11 @@ STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) ...@@ -54,11 +54,11 @@ STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
double frac; double frac;
if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
return 0.0; return 0.0;
frac = (double) wrd2 / 2147483648.0 + frac = (double) wrd2 / 2147483648.0 +
(double) wrd3 / 9223372036854775808.0; (double) wrd3 / 9223372036854775808.0;
if (wrd1 & 0x80000000) if (wrd1 & 0x80000000)
frac = -frac; frac = -frac;
return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
} }
#endif #endif
...@@ -70,22 +70,22 @@ STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u3 ...@@ -70,22 +70,22 @@ STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u3
double frac; double frac;
if (src == 0.0) { if (src == 0.0) {
*wrd1 = 0; *wrd1 = 0;
*wrd2 = 0; *wrd2 = 0;
*wrd3 = 0; *wrd3 = 0;
return; return;
} }
if (src < 0) { if (src < 0) {
*wrd1 = 0x80000000; *wrd1 = 0x80000000;
src = -src; src = -src;
} else { } else {
*wrd1 = 0; *wrd1 = 0;
} }
frac = frexp (src, &expon); frac = frexp (src, &expon);
frac += 0.5 / 18446744073709551616.0; frac += 0.5 / 18446744073709551616.0;
if (frac >= 1.0) { if (frac >= 1.0) {
frac /= 2.0; frac /= 2.0;
expon++; expon++;
} }
*wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
*wrd2 = (uae_u32) (frac * 4294967296.0); *wrd2 = (uae_u32) (frac * 4294967296.0);
...@@ -99,11 +99,11 @@ STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2) ...@@ -99,11 +99,11 @@ STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2)
double frac; double frac;
if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
return 0.0; return 0.0;
frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 + frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 +
(double) wrd2 / 4503599627370496.0; (double) wrd2 / 4503599627370496.0;
if (wrd1 & 0x80000000) if (wrd1 & 0x80000000)
frac = -frac; frac = -frac;
return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023); return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023);
} }
#endif #endif
...@@ -116,21 +116,21 @@ STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) ...@@ -116,21 +116,21 @@ STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
double frac; double frac;
if (src == 0.0) { if (src == 0.0) {
*wrd1 = 0; *wrd1 = 0;
*wrd2 = 0; *wrd2 = 0;
return; return;
} }
if (src < 0) { if (src < 0) {
*wrd1 = 0x80000000; *wrd1 = 0x80000000;
src = -src; src = -src;
} else { } else {
*wrd1 = 0; *wrd1 = 0;
} }
frac = frexp (src, &expon); frac = frexp (src, &expon);
frac += 0.5 / 9007199254740992.0; frac += 0.5 / 9007199254740992.0;
if (frac >= 1.0) { if (frac >= 1.0) {
frac /= 2.0; frac /= 2.0;
expon++; expon++;
} }
tmp = (uae_u32) (frac * 2097152.0); tmp = (uae_u32) (frac * 2097152.0);
*wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff); *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff);
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
/* Seems the same routines copy back and forth ;-) */ /* Seems the same routines copy back and forth ;-) */
#define PIC_READ (SPECIAL_MEM_READ|SPECIAL_MEM_WRITE) #define PIC_READ (SPECIAL_MEM_READ|SPECIAL_MEM_WRITE)
#define PIC_WRITE (SPECIAL_MEM_READ|SPECIAL_MEM_WRITE) #define PIC_WRITE (SPECIAL_MEM_READ|SPECIAL_MEM_WRITE)
#define JAM1 0 #define JAM1 0
#define JAM2 1 #define JAM2 1
......
...@@ -276,9 +276,15 @@ int scsiemul_switchscsi (TCHAR *name) ...@@ -276,9 +276,15 @@ int scsiemul_switchscsi (TCHAR *name)
{ {
struct devstruct *dev = NULL; struct devstruct *dev = NULL;
struct device_info *discsi, discsi2; struct device_info *discsi, discsi2;
int i, j; int i, j, opened[MAX_TOTAL_DEVICES];
bool wasopen = false;
for (i = 0; i < MAX_TOTAL_DEVICES; i++)
opened[i] = sys_command_isopen (i);
dev = &devst[0]; dev = &devst[0];
if ((dev->allow_ioctl || dev->allow_scsi) && dev->opencnt)
wasopen = true;
if (dev->allow_scsi) if (dev->allow_scsi)
sys_command_close (DF_SCSI, dev->unitnum); sys_command_close (DF_SCSI, dev->unitnum);
if (dev->allow_ioctl) if (dev->allow_ioctl)
...@@ -307,7 +313,7 @@ int scsiemul_switchscsi (TCHAR *name) ...@@ -307,7 +313,7 @@ int scsiemul_switchscsi (TCHAR *name)
dev->drivetype = discsi->type; dev->drivetype = discsi->type;
memcpy (&dev->di, discsi, sizeof (struct device_info)); memcpy (&dev->di, discsi, sizeof (struct device_info));
dev->iscd = 1; dev->iscd = 1;
write_log ("%s mounted as uaescsi.device:0 (SCSI=%d)\n", discsi->label, dev->allow_scsi); write_log ("%s mounted as uaescsi.device:0 (SCSI=%d IOCTL=%d)\n", discsi->label, dev->allow_scsi, dev->allow_ioctl);
if (dev->aunit >= 0) { if (dev->aunit >= 0) {
struct priv_devstruct *pdev = &pdevst[dev->aunit]; struct priv_devstruct *pdev = &pdevst[dev->aunit];
setpdev (pdev, dev); setpdev (pdev, dev);
...@@ -318,7 +324,7 @@ int scsiemul_switchscsi (TCHAR *name) ...@@ -318,7 +324,7 @@ int scsiemul_switchscsi (TCHAR *name)
} }
} }
} }
if (devst[0].opencnt == 0) if (opened[i] == 0 && !wasopen)
sys_command_close (mode, i); sys_command_close (mode, i);
} }
i++; i++;
...@@ -335,6 +341,7 @@ static int scsiemul_switchemu (const TCHAR *name) ...@@ -335,6 +341,7 @@ static int scsiemul_switchemu (const TCHAR *name)
if (!device_func_init (DEVICE_TYPE_ANY | DEVICE_TYPE_ALLOWEMU)) if (!device_func_init (DEVICE_TYPE_ANY | DEVICE_TYPE_ALLOWEMU))
return -1; return -1;
int opened = sys_command_isopen (0);
if (sys_command_open (DF_IOCTL, 0)) { if (sys_command_open (DF_IOCTL, 0)) {
if (discsi = sys_command_info (DF_IOCTL, 0, &discsi2)) { if (discsi = sys_command_info (DF_IOCTL, 0, &discsi2)) {
dev = &devst[0]; dev = &devst[0];
...@@ -351,7 +358,7 @@ static int scsiemul_switchemu (const TCHAR *name) ...@@ -351,7 +358,7 @@ static int scsiemul_switchemu (const TCHAR *name)
} }
dev->di.media_inserted = 0; dev->di.media_inserted = 0;
} }
if (devst[0].opencnt == 0) if (!opened)
sys_command_close (DF_IOCTL, 0); sys_command_close (DF_IOCTL, 0);
return 0; return 0;
} }
......
...@@ -445,7 +445,7 @@ configure:4344: $? = 0 ...@@ -445,7 +445,7 @@ configure:4344: $? = 0
configure:4344: result: yes configure:4344: result: yes
configure:4350: checking for _doprnt configure:4350: checking for _doprnt
configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/cc65mTgk.o: In function `main': /tmp/cczRCLXC.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt' /home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4350: $? = 1 configure:4350: $? = 1
...@@ -533,7 +533,7 @@ configure:4364: $? = 0 ...@@ -533,7 +533,7 @@ configure:4364: $? = 0
configure:4364: result: yes configure:4364: result: yes
configure:4364: checking for strcmpi configure:4364: checking for strcmpi
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/cc7AqVhB.o: In function `main': /tmp/ccZxlONG.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi' /home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4364: $? = 1 configure:4364: $? = 1
...@@ -613,7 +613,7 @@ configure: failed program was: ...@@ -613,7 +613,7 @@ configure: failed program was:
configure:4364: result: no configure:4364: result: no
configure:4364: checking for stricmp configure:4364: checking for stricmp
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/ccqJO3OI.o: In function `main': /tmp/ccRpVkEO.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp' /home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4364: $? = 1 configure:4364: $? = 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment