syncing 2.3.0

parent 8f059ce4
......@@ -16,10 +16,14 @@
#include "scsidev.h"
#include "savestate.h"
#include "crc32.h"
#include "threaddep/thread.h"
#include "execio.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
int log_scsiemu = 0;
#define PRE_INSERT_DELAY (3 * (currprefs.ntscmode ? 60 : 50))
static int scsiemu[MAX_TOTAL_SCSI_DEVICES];
......@@ -28,6 +32,8 @@ struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES];
static int openlist[MAX_TOTAL_SCSI_DEVICES];
static int waspaused[MAX_TOTAL_SCSI_DEVICES];
static int delayed[MAX_TOTAL_SCSI_DEVICES];
static uae_sem_t unitsem[MAX_TOTAL_SCSI_DEVICES];
static int unitsem_cnt[MAX_TOTAL_SCSI_DEVICES];
/* convert minutes, seconds and frames -> logical sector number */
int msf2lsn (int msf)
......@@ -248,9 +254,58 @@ void blkdev_fix_prefs (struct uae_prefs *p)
}
static bool getsem2 (int unitnum, bool dowait)
{
if (unitsem[unitnum] == NULL)
uae_sem_init (&unitsem[unitnum], 0, 1);
bool gotit = false;
if (dowait) {
uae_sem_wait (&unitsem[unitnum]);
gotit = true;
} else {
gotit = uae_sem_trywait (&unitsem[unitnum]) == 0;
}
if (gotit)
unitsem_cnt[unitnum]++;
if (unitsem_cnt[unitnum] > 1)
write_log ("CD: unitsem%d acquire mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]);
return gotit;
}
static bool getsem (int unitnum)
{
return getsem2 (unitnum, false);
}
static void freesem (int unitnum)
{
unitsem_cnt[unitnum]--;
if (unitsem_cnt[unitnum] < 0)
write_log ("CD: unitsem%d release mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]);
uae_sem_post (&unitsem[unitnum]);
}
static void sys_command_close_internal (int unitnum)
{
getsem2 (unitnum, true);
waspaused[unitnum] = 0;
if (openlist[unitnum] <= 0)
write_log ("BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]);
if (device_func[unitnum]) {
device_func[unitnum]->closedev (unitnum);
if (openlist[unitnum] > 0)
openlist[unitnum]--;
}
freesem (unitnum);
if (openlist[unitnum] == 0) {
uae_sem_destroy (&unitsem[unitnum]);
unitsem[unitnum] = NULL;
}
}
static int sys_command_open_internal (int unitnum, const TCHAR *ident, unsigned int csu)
{
int ret = 0;
if (unitsem[unitnum] == NULL)
uae_sem_init (&unitsem[unitnum], 0, 1);
getsem2 (unitnum, true);
if (openlist[unitnum])
write_log ("BUG unit %d open: opencnt=%d!\n", unitnum, openlist[unitnum]);
if (device_func[unitnum]) {
......@@ -258,6 +313,7 @@ static int sys_command_open_internal (int unitnum, const TCHAR *ident, unsigned
if (ret)
openlist[unitnum]++;
}
freesem (unitnum);
return ret;
}
......@@ -373,17 +429,9 @@ int sys_command_open (int unitnum)
return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL, CD_STANDARD_UNIT_DEFAULT);
}
void sys_command_close (int unitnum)
{
waspaused[unitnum] = 0;
if (openlist[unitnum] <= 0)
write_log ("BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]);
if (device_func[unitnum]) {
device_func[unitnum]->closedev (unitnum);
if (openlist[unitnum] > 0)
openlist[unitnum]--;
}
sys_command_close_internal (unitnum);
}
void blkdev_cd_change (int unitnum, const TCHAR *name)
......@@ -460,6 +508,8 @@ static void check_changes (int unitnum)
changed = true;
if (changed) {
if (unitsem[unitnum])
getsem2 (unitnum, true);
cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse;
_tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name);
changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0;
......@@ -481,12 +531,16 @@ static void check_changes (int unitnum)
#ifdef RETROPLATFORM
rp_cd_image_change (unitnum, NULL);
#endif
if (unitsem[unitnum])
freesem (unitnum);
}
if (imagechangetime[unitnum] == 0)
return;
imagechangetime[unitnum]--;
if (imagechangetime[unitnum] > 0)
return;
if (unitsem[unitnum])
getsem2 (unitnum, true);
_tcscpy (currprefs.cdslots[unitnum].name, newimagefiles[unitnum]);
_tcscpy (changed_prefs.cdslots[unitnum].name, newimagefiles[unitnum]);
currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = cdimagefileinuse[unitnum];
......@@ -508,6 +562,9 @@ static void check_changes (int unitnum)
#ifdef RETROPLATFORM
rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name);
#endif
if (unitsem[unitnum])
freesem (unitnum);
config_changed = 1;
}
......@@ -539,8 +596,11 @@ static int failunit (int unitnum)
static int audiostatus (int unitnum)
{
if (!getsem (unitnum))
return 0;
uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, sizeof (cmd), 0);
freesem (unitnum);
if (!p)
return 0;
return p[1];
......@@ -551,13 +611,19 @@ int sys_command_cd_pause (int unitnum, int paused)
{
if (failunit (unitnum))
return -1;
if (!getsem (unitnum))
return 0;
int v;
if (device_func[unitnum]->pause == NULL) {
int as = audiostatus (unitnum);
uae_u8 cmd[10] = {0x4b,0,0,0,0,0,0,0,paused?0:1,0};
do_scsi (unitnum, cmd, sizeof cmd);
return as == AUDIO_STATUS_PAUSED;
v = as == AUDIO_STATUS_PAUSED;
} else {
v = device_func[unitnum]->pause (unitnum, paused);
}
return device_func[unitnum]->pause (unitnum, paused);
freesem (unitnum);
return v;
}
/* stop CD audio */
......@@ -565,48 +631,26 @@ void sys_command_cd_stop (int unitnum)
{
if (failunit (unitnum))
return;
if (!getsem (unitnum))
return;
if (device_func[unitnum]->stop == NULL) {
int as = audiostatus (unitnum);
uae_u8 cmd[6] = {0x4e,0,0,0,0,0};
do_scsi (unitnum, cmd, sizeof cmd);
return;
}
} else {
device_func[unitnum]->stop (unitnum);
}
#if 0
static int adjustplaypos (int unitnum, int startlsn)
{
uae_u8 q[SUBQ_SIZE];
if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1))
return startlsn;
int otrack = frombcd (q[4 + 1]);
int lsn = startlsn;
int max = 150;
while (max-- > 0 && startlsn > 0) {
if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1))
break;
int track = frombcd (q[4 + 1]);
int idx = frombcd (q[4 + 2]);
//write_log ("%d %d\n", track, idx);
if (idx != 0 || otrack != track)
break;
startlsn--;
}
if (lsn != startlsn)
write_log ("CD play adjust %d -> %d\n", lsn, startlsn);
startlsn -= 10;
if (startlsn < 0)
startlsn = 0;
return startlsn;
freesem (unitnum);
}
#endif
/* play CD audio */
int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->play == NULL) {
uae_u8 cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
int startmsf = lsn2msf (startlsn);
......@@ -618,145 +662,209 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan)
cmd[6] = (uae_u8)(endmsf >> 16);
cmd[7] = (uae_u8)(endmsf >> 8);
cmd[8] = (uae_u8)(endmsf >> 0);
return do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1;
v = do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1;
} else {
v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
}
//startlsn = adjustplaypos (unitnum, startlsn);
return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
freesem (unitnum);
return v;
}
/* play CD audio with subchannels */
int sys_command_cd_play2 (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->play == NULL)
return sys_command_cd_play (unitnum, startlsn, endlsn, scan);
//startlsn = adjustplaypos (unitnum, startlsn);
return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
v = sys_command_cd_play (unitnum, startlsn, endlsn, scan);
else
v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
freesem (unitnum);
return v;
}
/* set CD audio volume */
uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_right)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->volume == NULL)
return -1;
return device_func[unitnum]->volume (unitnum, volume_left, volume_right);
v = -1;
else
v = device_func[unitnum]->volume (unitnum, volume_left, volume_right);
freesem (unitnum);
return v;
}
/* read qcode */
int sys_command_cd_qcode (int unitnum, uae_u8 *buf)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->qcode == NULL) {
uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0};
return do_scsi2 (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
v = do_scsi2 (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
} else {
v = device_func[unitnum]->qcode (unitnum, buf, -1);
}
return device_func[unitnum]->qcode (unitnum, buf, -1);
freesem (unitnum);
return v;
};
/* read table of contents */
int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->toc == NULL) {
uae_u8 buf[4 + 8 * 103];
int size = sizeof buf;
uae_u8 cmd [10] = { 0x43,0,2,0,0,0,0,(uae_u8)(size>>8),(uae_u8)(size&0xff),0};
if (do_scsi2 (unitnum, cmd, sizeof cmd, buf, size)) {
// toc parse to do
return 0;
v = 0;
}
return 0;
v = 0;
} else {
v = device_func[unitnum]->toc (unitnum, toc);
}
return device_func[unitnum]->toc (unitnum, toc);
freesem (unitnum);
return v;
}
/* read one cd sector */
int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->read == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
cmd[1] = 2 << 3; // 2048
if (!do_scsi2 (unitnum, cmd, sizeof cmd, data, size * 2048))
cmd[1] = 4 << 3; // 2048 mode2
return do_scsi2 (unitnum, cmd, sizeof cmd, data, size * 2048);
v = do_scsi2 (unitnum, cmd, sizeof cmd, data, size * 2048);
} else {
v = device_func[unitnum]->read (unitnum, data, block, size);
}
return device_func[unitnum]->read (unitnum, data, block, size);
freesem (unitnum);
return v;
}
int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize)
{
int v;
if (failunit (unitnum))
return -1;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->rawread == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
return do_scsi2 (unitnum, cmd, sizeof cmd, data, size * sectorsize);
v = do_scsi2 (unitnum, cmd, sizeof cmd, data, size * sectorsize);
} else {
v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
}
return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
freesem (unitnum);
return v;
}
int sys_command_cd_rawread2 (int unitnum, uae_u8 *data, int block, int size, int sectorsize, uae_u8 sectortype, uae_u8 scsicmd9, uae_u8 subs)
{
int v;
if (failunit (unitnum))
return -1;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->rawread == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
return do_scsi2 (unitnum, cmd, sizeof cmd, data, size * sectorsize);
v = do_scsi2 (unitnum, cmd, sizeof cmd, data, size * sectorsize);
} else {
v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
}
return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
freesem (unitnum);
return v;
}
/* read block */
int sys_command_read (int unitnum, uae_u8 *data, int block, int size)
{
int v;
if (failunit (unitnum))
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum]->read == NULL) {
uae_u8 cmd[12] = { 0xa8, 0, 0, 0, 0, 0, size >> 24, size >> 16, size >> 8, size >> 0, 0, 0 };
cmd[2] = (uae_u8)(block >> 24);
cmd[3] = (uae_u8)(block >> 16);
cmd[4] = (uae_u8)(block >> 8);
cmd[5] = (uae_u8)(block >> 0);
return do_scsi2 (unitnum, cmd, sizeof cmd, data, size * 2048);
v = do_scsi2 (unitnum, cmd, sizeof cmd, data, size * 2048);
} else {
v = device_func[unitnum]->read (unitnum, data, block, size);
}
return device_func[unitnum]->read (unitnum, data, block, size);
freesem (unitnum);
return v;
}
/* write block */
int sys_command_write (int unitnum, uae_u8 *data, int offset, int size)
{
int v;
if (failunit (unitnum))
return 0;
if (device_func[unitnum]->write == NULL)
if (!getsem (unitnum))
return 0;
return device_func[unitnum]->write (unitnum, data, offset, size);
if (device_func[unitnum]->write == NULL) {
v = 0;
} else {
v = device_func[unitnum]->write (unitnum, data, offset, size);
}
freesem (unitnum);
return v;
}
int sys_command_ismedia (int unitnum, int quick)
{
int v;
if (failunit (unitnum))
return -1;
if (delayed[unitnum])
return 0;
if (!getsem (unitnum))
return 0;
if (device_func[unitnum] == NULL) {
uae_u8 cmd[6] = { 0, 0, 0, 0, 0, 0 };
return do_scsi (unitnum, cmd, sizeof cmd);
v = do_scsi (unitnum, cmd, sizeof cmd);
} else {
return device_func[unitnum]->ismedia (unitnum, quick);
v = device_func[unitnum]->ismedia (unitnum, quick);
}
freesem (unitnum);
return v;
}
struct device_info *sys_command_info (int unitnum, struct device_info *di, int quick)
{
if (failunit (unitnum))
return NULL;
if (!getsem (unitnum))
return 0;
struct device_info *di2 = device_func[unitnum]->info (unitnum, di, quick);
if (di2 && delayed[unitnum])
di2->media_inserted = 0;
freesem (unitnum);
return di2;
}
......@@ -888,9 +996,12 @@ static bool nodisk (struct device_info *di)
}
static uae_u64 cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len)
{
if (device_func[unitnum]->read (unitnum, dataptr, offset, len))
if (!getsem (unitnum))
return 0;
int v = device_func[unitnum]->read (unitnum, dataptr, offset, len);
freesem (unitnum);
if (v)
return len;
else
return 0;
}
......@@ -996,6 +1107,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
scsi_len = 0;
goto end;
}
if (log_scsiemu)
write_log ("SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n", unitnum,
cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6],
cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11],
......@@ -1070,6 +1182,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
int dbd = cmdbuf[1] & 8;
if (cmdbuf[0] == 0x5a)
dbd = 1;
if (log_scsiemu)
write_log ("MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd);
p = r;
if (cmdbuf[0] == 0x5a) {
......@@ -1545,7 +1658,7 @@ end:
*data_len = scsi_len;
*reply_len = lr;
*sense_len = ls;
if (cmdbuf[0])
if (cmdbuf[0] && log_scsiemu)
write_log ("-> DATAOUT=%d ST=%d SENSELEN=%d\n", scsi_len, status, ls);
return status;
}
......@@ -1571,7 +1684,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as)
as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */
if (as->status) {
io_error = 45; /* HFERR_BadStatus */
io_error = IOERR_BadStatus;
as->sense_len = senselen;
as->actual = 0; /* scsi_Actual */
} else {
......@@ -1585,7 +1698,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as)
as->sensedata[i] = 0;
sactual = 0;
if (datalen < 0) {
io_error = 20; /* io_Error, but not specified */
io_error = IOERR_NotSpecified;
as->actual = 0; /* scsi_Actual */
} else {
as->len = datalen;
......@@ -1624,11 +1737,13 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd)
bank = &get_mem_bank (ap);
if (!bank || !bank->check(ap, as.len))
return -5;
return IOERR_BADADDRESS;
as.data = bank->xlateaddr (ap);
ap = get_long (acmd + 12);
as.cmd_len = get_word (acmd + 16);
if (as.cmd_len > sizeof as.cmd)
return IOERR_BADLENGTH;
for (i = 0; i < as.cmd_len; i++)
as.cmd[i] = get_byte (ap++);
while (i < sizeof as.cmd)
......
......@@ -62,7 +62,7 @@ struct cdunit {
uae_u64 cdsize;
int blocksize;
int cdda_play_finished;
int cdda_play_state;
int cdda_play;
int cdda_paused;
int cdda_volume[2];
......@@ -70,7 +70,8 @@ struct cdunit {
int cd_last_pos;
int cdda_start, cdda_end;
play_subchannel_callback cdda_subfunc;
bool slowunit;
play_status_callback cdda_statusfunc;
int cdda_delay, cdda_delay_frames;
int imagechange;
TCHAR newfile[MAX_DPATH];
......@@ -92,11 +93,14 @@ static struct cdunit *unitisopen (int unitnum)
return NULL;
}
static struct cdtoc *findtoc (struct cdunit *cdu, int *sectorp)
{
int i;
int sector;
if (*sectorp < 0)
return NULL;
sector = *sectorp;
for (i = 0; i <= cdu->tracks; i++) {
struct cdtoc *t = &cdu->toc[i];
......@@ -260,7 +264,7 @@ static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
}
}
static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
static int getsub_deinterleaved (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
{
int ret = 0;
uae_sem_wait (&cdu->sub_sem);
......@@ -303,31 +307,29 @@ static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
return ret;
}
static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector)
static void dosub (struct cdunit *cdu, uae_u8 *subbuf)
{
uae_u8 *d;
uae_u8 subbuf[SUB_CHANNEL_SIZE];
uae_u8 subbuf2[SUB_CHANNEL_SIZE];
if (!cdu->cdda_subfunc)
return;
if (!t) {
memset (subbuf, 0, sizeof subbuf);
cdu->cdda_subfunc (subbuf, 1);
if (!subbuf) {
memset (subbuf2, 0, sizeof subbuf2);
cdu->cdda_subfunc (subbuf2, 1);
return;
}
memset (subbuf, 0, SUB_CHANNEL_SIZE);
int mode = getsub (subbuf, cdu, t, sector);
if (mode == 2) { // deinterleaved -> interleaved
sub_to_interleaved (subbuf, subbuf2);
d = subbuf2;
} else {
d = subbuf;
}
cdu->cdda_subfunc (d, 1);
cdu->cdda_subfunc (subbuf2, 1);
}
static int setstate (struct cdunit *cdu, int state)
{
cdu->cdda_play_state = state;
if (cdu->cdda_statusfunc)
return cdu->cdda_statusfunc (cdu->cdda_play_state);
return 0;
}
static void *cdda_unpack_func (void *v)
{
......@@ -387,8 +389,9 @@ static void *cdda_play_func (void *v)
MMRESULT mmr;
int volume[2], volume_main;
int oldplay;
int idleframes;
bool foundsub;
struct cdunit *cdu = (struct cdunit*)v;
int firstloops;
for (i = 0; i < 2; i++) {
memset (&whdr[i], 0, sizeof (WAVEHDR));
......@@ -426,17 +429,19 @@ static void *cdda_play_func (void *v)
if (oldplay != cdu->cdda_play) {
struct cdtoc *t;
int sector;
struct _timeb tb;
int sector, diff;
struct _timeb tb1, tb2;
_ftime (&tb);
idleframes = 0;
foundsub = false;
_ftime (&tb1);
cdda_pos = cdu->cdda_start;
oldplay = cdu->cdda_play;
cdu->cd_last_pos = cdda_pos;
sector = cdu->cdda_start;
sector = cdu->cd_last_pos = cdda_pos;
t = findtoc (cdu, &sector);
if (!t) {
write_log ("IMAGE CDDA: illegal sector number %d\n", cdu->cdda_start);
setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
} else {
write_log ("IMAGE CDDA: playing from %d to %d, track %d ('%s', offset %d, secoffset %d)\n",
cdu->cdda_start, cdu->cdda_end, t->track, t->fname, t->offset, sector);
......@@ -450,13 +455,46 @@ static void *cdda_play_func (void *v)
while (cdimage_unpack_active == 0)
Sleep (10);
}
firstloops = cdu->slowunit ? 150 : 30;
idleframes = cdu->cdda_delay_frames;
while (cdu->cdda_paused && cdu->cdda_play > 0) {
Sleep (10);
firstloops = -1;
idleframes = -1;
}
if (firstloops > 0)
firstloops /= num_sectors;
if (cdu->cdda_scan == 0) {
// find possible P-subchannel=1 and fudge starting point so that
// buggy CD32/CDTV software CD+G handling does not miss any frames
bool seenindex = false;
for (sector = cdda_pos - 200; sector < cdda_pos; sector++) {
int sec = sector;
t = findtoc (cdu, &sec);
if (t) {
uae_u8 subbuf[SUB_CHANNEL_SIZE];
getsub_deinterleaved (subbuf, cdu, t, sector);
if (seenindex) {
for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) {
if (subbuf[i]) { // non-zero R-W subchannels
int diff = cdda_pos - sector + 2;
write_log ("-> CD+G start pos fudge -> %d (%d)\n", sector, -diff);
idleframes -= diff;
cdda_pos = sector;
break;
}
}
} else if (subbuf[0] == 0xff) { // P == 1?
seenindex = true;
}
}
}
}
cdda_pos -= idleframes;
_ftime (&tb2);
diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm);
diff -= cdu->cdda_delay;
if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0)
Sleep (-diff);
setstate (cdu, AUDIO_STATUS_IN_PROGRESS);
}
while (!(whdr[bufnum].dwFlags & WHDR_DONE)) {
......@@ -466,8 +504,10 @@ static void *cdda_play_func (void *v)
}
bufon[bufnum] = 0;
if (!isaudiotrack (&cdu->di.toc, cdda_pos))
if (idleframes <= 0 && !isaudiotrack (&cdu->di.toc, cdda_pos)) {
setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
goto end; // data track?
}
if ((cdda_pos < cdu->cdda_end || cdu->cdda_end == 0xffffffff) && !cdu->cdda_paused && cdu->cdda_play > 0) {
struct cdtoc *t;
......@@ -478,31 +518,16 @@ static void *cdda_play_func (void *v)
memset (px[bufnum], 0, num_sectors * 2352);
if (firstloops > 0) {
firstloops--;
for (cnt = 0; cnt < num_sectors; cnt++)
dosub (cdu, NULL, -1);
} else {
for (cnt = 0; cnt < num_sectors; cnt++) {
uae_u8 *dst = px[bufnum] + cnt * 2352;
uae_u8 subbuf[SUB_CHANNEL_SIZE];
sector = cdda_pos;
if (cdu->cdda_scan) {
cdda_pos += cdu->cdda_scan;
if (cdda_pos < 0)
cdda_pos = 0;
} else {
cdda_pos++;
}
if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
dofinish = 1;
memset (subbuf, 0, SUB_CHANNEL_SIZE);
t = findtoc (cdu, &sector);
if (t) {
if (t->handle && !(t->ctrl & 4)) {
uae_u8 *dst = px[bufnum] + cnt * t->size;
int totalsize = t->size + t->skipsize;
if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) {
if (t->filesize >= sector * totalsize + t->offset + t->size)
......@@ -514,12 +539,36 @@ static void *cdda_play_func (void *v)
}
}
}
dosub (cdu, t, cdda_pos);
getsub_deinterleaved (subbuf, cdu, t, cdda_pos);
}
if (idleframes > 0) {
idleframes--;
memset (dst, 0, 2352);
memset (subbuf, 0, SUB_CHANNEL_SIZE);
}
if (cdda_pos < cdu->cdda_start && cdu->cdda_scan == 0)
memset (dst, 0, 2352);
dosub (cdu, subbuf);
if (cdu->cdda_scan) {
cdda_pos += cdu->cdda_scan;
if (cdda_pos < 0)
cdda_pos = 0;
} else {
cdda_pos++;
}
if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
dofinish = 1;
}
if (idleframes <= 0)
cdu->cd_last_pos = cdda_pos;
volume_main = currprefs.sound_volume;
int vol_mult[2];
for (int j = 0; j < 2; j++) {
......@@ -543,10 +592,8 @@ static void *cdda_play_func (void *v)
break;
}
cdu->cd_last_pos = cdda_pos;
if (dofinish) {
cdu->cdda_play_finished = 1;
setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE);
cdu->cdda_play = -1;
cdda_pos = cdu->cdda_end + 1;
}
......@@ -592,8 +639,8 @@ static void cdda_stop (struct cdunit *cdu)
Sleep (10);
}
}
cdu->cdda_play_finished = 0;
cdu->cdda_paused = 0;
cdu->cdda_play_state = 0;
}
......@@ -616,19 +663,24 @@ static int command_stop (int unitnum)
return 1;
}
static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_subchannel_callback subfunc)
static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc)
{
struct cdunit *cdu = unitisopen (unitnum);
if (!cdu)
return 0;
if (!isaudiotrack (&cdu->di.toc, startlsn))
return 0;
cdu->cdda_play_finished = 0;
cdu->cd_last_pos = startlsn;
cdu->cdda_start = startlsn;
cdu->cdda_end = endlsn;
cdu->cdda_subfunc = subfunc;
cdu->cdda_statusfunc = statusfunc;
cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
cdu->cdda_delay = setstate (cdu, -1);
cdu->cdda_delay_frames = setstate (cdu, -2);
setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED);
if (!isaudiotrack (&cdu->di.toc, startlsn)) {
setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
return 0;
}
if (!cdu->cdda_play)
uae_start_thread ("cdimage_cdda_play", cdda_play_func, cdu, NULL);
cdu->cdda_play++;
......@@ -650,14 +702,10 @@ static int command_qcode (int unitnum, uae_u8 *buf, int sector)
memset (buf, 0, SUBQ_SIZE);
p = buf;
status = AUDIO_STATUS_NO_STATUS;
if (cdu->cdda_play > 0) {
status = AUDIO_STATUS_IN_PROGRESS;
if (cdu->cdda_paused)
status = cdu->cdda_play_state;
if (cdu->cdda_play > 0 && cdu->cdda_paused)
status = AUDIO_STATUS_PAUSED;
} else if (cdu->cdda_play_finished) {
status = AUDIO_STATUS_PLAY_COMPLETE;
}
if (sector < 0)
pos = cdu->cd_last_pos;
else
......@@ -681,7 +729,7 @@ static int command_qcode (int unitnum, uae_u8 *buf, int sector)
}
if (!td)
return 0;
getsub (subbuf, cdu, td, pos);
getsub_deinterleaved (subbuf, cdu, td, pos);
memcpy (p, subbuf + 12, 12);
// write_log ("%6d %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n",
// pos, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11]);
......@@ -710,7 +758,8 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
struct cdtoc *t = findtoc (cdu, &sector);
if (!t || t->handle == NULL)
return 0;
goto end;
cdda_stop (cdu);
if (sectorsize > 0) {
if (sectorsize == 2352 && t->size == 2048) {
......@@ -762,21 +811,27 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
int edcecc = (cmd9 >> 3) & 1;
int errorfield = (cmd9 >> 1) & 3;
uae_u8 subs = extra & 7;
if (subs != 0 && subs != 1 && subs != 2 && subs != 4)
return -1;
if (subs != 0 && subs != 1 && subs != 2 && subs != 4) {
ret = -1;
goto end;
}
if (isaudiotrack (&cdu->di.toc, sector)) {
if (sectortype != 0 && sectortype != 1)
return -2;
if (t->size != 2352)
return -1;
if (sectortype != 0 && sectortype != 1) {
ret = -2;
goto end;
}
if (t->size != 2352) {
ret = -1;
goto end;
}
for (int i = 0; i < size; i++) {
zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
zfile_fread (data, t->size, 1, t->handle);
uae_u8 *p = data + t->size;
if (subs) {
uae_u8 subdata[SUB_CHANNEL_SIZE];
getsub (subdata, cdu, t, sector);
getsub_deinterleaved (subdata, cdu, t, sector);
if (subs == 4) { // all, de-interleaved
memcpy (p, subdata, SUB_CHANNEL_SIZE);
p += SUB_CHANNEL_SIZE;
......@@ -794,6 +849,7 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
}
}
}
end:
return ret;
}
......@@ -807,7 +863,7 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size)
struct cdtoc *t = findtoc (cdu, &sector);
if (!t || t->handle == NULL)
return NULL;
return 0;
cdda_stop (cdu);
if (t->size == 2048) {
zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
......@@ -1553,7 +1609,6 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
return 1;
}
static int ismedia (int unitnum, int quick)
{
struct cdunit *cdu = &cdunits[unitnum];
......@@ -1569,7 +1624,6 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
if (!cdu->enabled)
return 0;
di->open = cdu->open;
di->slow_unit = cdu->slowunit;
di->removable = 1;
di->bus = unitnum;
di->target = 0;
......@@ -1621,36 +1675,35 @@ static void unload_image (struct cdunit *cdu)
static int open_device (int unitnum, const TCHAR *ident, int flags)
{
struct cdunit *cdu = &cdunits[unitnum];
int ret = 0;
if (cdu->open)
return 0;
if (!cdu->open) {
uae_sem_init (&cdu->sub_sem, 0, 1);
parse_image (cdu, ident);
cdu->open = true;
cdu->enabled = true;
cdu->cdda_volume[0] = 0x7fff;
cdu->cdda_volume[1] = 0x7fff;
cdu->slowunit = (flags & 1) != 0;
blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
if (cdimage_unpack_thread == 0) {
init_comm_pipe (&unpack_pipe, 10, 1);
uae_start_thread ("cdimage_unpack", cdda_unpack_func, NULL, NULL);
while (cdimage_unpack_thread == 0)
Sleep (10);
}
return 1;
ret = 1;
}
blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
return ret;
}
static void close_device (int unitnum)
{
struct cdunit *cdu = &cdunits[unitnum];
if (cdu->open == false)
return;
if (cdu->open) {
cdda_stop (cdu);
unload_image (cdu);
uae_sem_destroy (&cdu->sub_sem);
cdu->open = false;
blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
if (cdimage_unpack_thread) {
cdimage_unpack_thread = 0;
write_comm_pipe_u32 (&unpack_pipe, -1, 0);
......@@ -1660,6 +1713,8 @@ static void close_device (int unitnum)
cdimage_unpack_thread = 0;
destroy_comm_pipe (&unpack_pipe);
}
}
blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
}
static void close_bus (void)
......@@ -1690,7 +1745,7 @@ static int open_bus (int flags)
}
struct device_functions devicefunc_cdimage = {
L"IMAGE",
"IMAGE",
open_bus, close_bus, open_device, close_device, info_device,
0, 0, 0,
command_pause, command_stop, command_play, command_volume, command_qcode,
......
......@@ -1769,9 +1769,9 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
return 0;
}
static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident)
static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags)
{
TCHAR *p;
const TCHAR *p;
int ver, rev, subver, subrev, round, i;
TCHAR model[64], *modelp;
struct romlist **rl;
......@@ -1796,7 +1796,7 @@ static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident)
pp1 = &subver;
pp2 = &subrev;
} else if (!_istdigit(c) && c != ' ') {
_tcsncpy (model, p - 1, (sizeof model) - 1);
_tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1);
p += _tcslen (model);
modelp = model;
}
......@@ -1811,7 +1811,7 @@ static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident)
}
}
if (*p == 0 || *p == ';') {
rl = getromlistbyident (ver, rev, subver, subrev, modelp, round);
rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0);
if (rl) {
for (i = 0; rl[i]; i++) {
if (round) {
......@@ -2102,15 +2102,15 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, TCHAR *option, TCHAR *va
return 1;
}
if (cfgfile_string (option, value, "kickstart_rom", p->romident, sizeof p->romident / sizeof (TCHAR))) {
decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident);
decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK);
return 1;
}
if (cfgfile_string (option, value, "kickstart_ext_rom", p->romextident, sizeof p->romextident / sizeof (TCHAR))) {
decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident);
decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
return 1;
}
if (cfgfile_string (option, value, "cart", p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident);
decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
return 1;
}
......
......@@ -635,12 +635,8 @@ static uae_u8 ReadCIAA (unsigned int addr)
action_replay_ciaread ();
#endif
tmp = DISK_status() & 0x3c;
tmp |= handle_joystick_buttons (ciaadra);
tmp |= handle_joystick_buttons (ciaapra, ciaadra);
tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
if (ciaadra & 0x40)
tmp = (tmp & ~0x40) | (ciaapra & 0x40);
if (ciaadra & 0x80)
tmp = (tmp & ~0x80) | (ciaapra & 0x80);
tmp = dongle_cia_read (0, reg, tmp);
#if DONGLE_DEBUG > 0
if (notinrom())
......
......@@ -888,7 +888,6 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
int canauto;
const TCHAR *ext;
gui_disk_image_change (dnum, fname);
drive_image_free (drv);
DISK_validate_filename (fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
drv->ddhd = 1;
......@@ -898,6 +897,8 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
drv->useturbo = 0;
drv->indexoffset = 0;
gui_disk_image_change (dnum, fname, drv->wrprot);
canauto = 0;
ext = _tcsrchr (fname, '.');
if (ext) {
......@@ -2023,7 +2024,7 @@ static void drive_eject (drive * drv)
#ifdef DRIVESOUND
driveclick_insert (drv - floppy, 1);
#endif
gui_disk_image_change (drv - floppy, NULL);
gui_disk_image_change (drv - floppy, NULL, drv->wrprot);
drive_image_free (drv);
drv->dskchange = 1;
drv->ddhd = 1;
......@@ -2187,7 +2188,7 @@ void DISK_reinsert (int num)
setdskchangetime (&floppy[num], 20);
}
int disk_setwriteprotect (int num, const TCHAR *name, int protect)
int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected)
{
int needwritefile, oldprotect;
struct zfile *zf1, *zf2;
......@@ -2209,7 +2210,7 @@ int disk_setwriteprotect (int num, const TCHAR *name, int protect)
if (needwritefile && zf2 == 0)
disk_creatediskfile (name2, 1, drvtype, NULL);
zfile_fclose (zf2);
if (protect && iswritefileempty (name)) {
if (writeprotected && iswritefileempty (name)) {
for (i = 0; i < MAX_FLOPPY_DRIVES; i++) {
if (!_tcscmp (name, floppy[i].newname))
drive_eject (&floppy[i]);
......@@ -2218,8 +2219,8 @@ int disk_setwriteprotect (int num, const TCHAR *name, int protect)
}
if (!needwritefile)
diskfile_readonly (name, protect);
diskfile_readonly (name2, protect);
diskfile_readonly (name, writeprotected);
diskfile_readonly (name2, writeprotected);
DISK_reinsert (num);
return 1;
}
......@@ -2234,7 +2235,7 @@ void disk_eject (int num)
update_drive_gui (num);
}
int DISK_history_add (const char *name, int idx, int type, int donotcheck)
int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck)
{
int i;
......@@ -2288,14 +2289,14 @@ int DISK_history_add (const char *name, int idx, int type, int donotcheck)
return 1;
}
char *DISK_history_get (int idx, int type)
TCHAR *DISK_history_get (int idx, int type)
{
if (idx >= MAX_PREVIOUS_FLOPPIES)
return NULL;
return dfxhistory[type][idx];
}
static void disk_insert_2 (int num, const char *name, int forced)
static void disk_insert_2 (int num, const TCHAR *name, int forced)
{
drive *drv = floppy + num;
......@@ -2322,13 +2323,13 @@ static void disk_insert_2 (int num, const char *name, int forced)
}
}
void disk_insert (int num, const char *name)
void disk_insert (int num, const TCHAR *name)
{
config_changed = 1;
// target_addtorecent (name, 0);
disk_insert_2 (num, name, 0);
}
void disk_insert_force (int num, const char *name)
void disk_insert_force (int num, const TCHAR *name)
{
disk_insert_2 (num, name, 1);
}
......@@ -2379,10 +2380,10 @@ int disk_empty (int num)
return drive_empty (floppy + num);
}
static char *tobin (uae_u8 v)
static TCHAR *tobin (uae_u8 v)
{
int i;
static char buf[10];
static TCHAR buf[10];
for( i = 7; i >= 0; i--)
buf[7 - i] = v & (1 << i) ? '1' : '0';
buf[i] = 0;
......
......@@ -650,7 +650,7 @@ void gui_message (const char *format,...)
restoreFullscreen ();
}
void gui_disk_image_change (int unitnum, const TCHAR *name) {}
void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
void gui_lock (void) {}
void gui_unlock (void) {}
......@@ -2725,7 +2725,7 @@ int gui_init (void)
return 1;
}
void gui_disk_image_change (int unitnum, const TCHAR *name) {}
void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
void gui_lock (void) {}
void gui_unlock (void) {}
......@@ -63,7 +63,7 @@ void gui_message (const char *format,...)
write_log (msg);
}
void gui_disk_image_change (int unitnum, const TCHAR *name) {}
void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
void gui_lock (void) {}
void gui_unlock (void) {}
......@@ -27,7 +27,7 @@ extern void DISK_update_adkcon (unsigned int hpos, uae_u16 v);
extern void DISK_hsync (void);
extern void DISK_reset (void);
extern int disk_getwriteprotect (const TCHAR *name);
extern int disk_setwriteprotect (int num, const TCHAR *name, int protect);
extern int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected);
extern void disk_creatediskfile (TCHAR *name, int type, drive_type adftype, TCHAR *disk_name);
extern void dumpdisk (void);
extern int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck);
......
......@@ -244,7 +244,6 @@ struct draw_info {
extern int next_sprite_entry;
extern struct decision line_decisions[2 * (MAXVPOS + 2) + 1];
extern struct draw_info line_drawinfo[2][2 * (MAXVPOS + 2) + 1];
extern uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2];
......
......@@ -7,27 +7,27 @@
#define IOERR_UNITBUSY -6
#define IOERR_SELFTEST -7
#define CDERR_NotSpecified 20 /* general catchall */
#define CDERR_NoSecHdr 21 /* couldn't even find a sector */
#define CDERR_BadSecPreamble 22 /* sector looked wrong */
#define CDERR_BadSecID 23 /* ditto */
#define CDERR_BadHdrSum 24 /* header had incorrect checksum */
#define CDERR_BadSecSum 25 /* data had incorrect checksum */
#define CDERR_TooFewSecs 26 /* couldn't find enough sectors */
#define CDERR_BadSecHdr 27 /* another "sector looked wrong" */
#define CDERR_WriteProt 28 /* can't write to a protected disk */
#define CDERR_NoDisk 29 /* no disk in the drive */
#define CDERR_SeekError 30 /* couldn't find track 0 */
#define CDERR_NoMem 31 /* ran out of memory */
#define CDERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */
#define CDERR_BadDriveType 33 /* not a drive cd.device understands */
#define CDERR_DriveInUse 34 /* someone else allocated the drive */
#define CDERR_PostReset 35 /* user hit reset; awaiting doom */
#define CDERR_BadDataType 36 /* data on disk is wrong type */
#define CDERR_InvalidState 37 /* invalid cmd under current conditions */
#define CDERR_Phase 42 /* illegal or unexpected SCSI phase */
#define CDERR_NoBoard 50 /* open failed for non-existant board */
#define IOERR_NotSpecified 20 /* general catchall */
#define IOERR_NoSecHdr 21 /* couldn't even find a sector */
#define IOERR_BadSecPreamble 22 /* sector looked wrong */
#define IOERR_BadSecID 23 /* ditto */
#define IOERR_BadHdrSum 24 /* header had incorrect checksum */
#define IOERR_BadSecSum 25 /* data had incorrect checksum */
#define IOERR_TooFewSecs 26 /* couldn't find enough sectors */
#define IOERR_BadSecHdr 27 /* another "sector looked wrong" */
#define IOERR_WriteProt 28 /* can't write to a protected disk */
#define IOERR_NoDisk 29 /* no disk in the drive */
#define IOERR_SeekError 30 /* couldn't find track 0 */
#define IOERR_NoMem 31 /* ran out of memory */
#define IOERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */
#define IOERR_BadDriveType 33 /* not a drive cd.device understands */
#define IOERR_DriveInUse 34 /* someone else allocated the drive */
#define IOERR_PostReset 35 /* user hit reset; awaiting doom */
#define IOERR_BadDataType 36 /* data on disk is wrong type */
#define IOERR_InvalidState 37 /* invalid cmd under current conditions */
#define IOERR_BadStatus 45
#define IOERR_Phase 42 /* illegal or unexpected SCSI phase */
#define IOERR_NoBoard 50 /* open failed for non-existant board */
#define TDERR_DiskChanged 29
......
......@@ -17,7 +17,7 @@ extern void gui_changesettings (void);
extern void gui_lock (void);
extern void gui_unlock (void);
extern void gui_flicker_led (int, int, int);
extern void gui_disk_image_change (int, const TCHAR *);
extern void gui_disk_image_change (int, const TCHAR *, bool writeprotected);
extern unsigned int gui_ledstate;
extern void gui_display (int shortcut);
......
......@@ -106,7 +106,7 @@ INPUTEVENT_END
extern void handle_cd32_joystick_cia (uae_u8, uae_u8);
extern uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra);
extern uae_u8 handle_joystick_buttons (uae_u8);
extern uae_u8 handle_joystick_buttons (uae_u8, uae_u8);
extern int getbuttonstate (int joy, int button);
extern int getjoystate (int joy);
......@@ -162,7 +162,7 @@ extern void inputdevice_hsync (void);
extern void inputdevice_reset (void);
//extern void write_inputdevice_config (struct uae_prefs *p, struct zfile *f);
extern void read_inputdevice_config (struct uae_prefs *p, TCHAR *option, TCHAR *value);
extern void read_inputdevice_config (struct uae_prefs *p, const TCHAR *option, TCHAR *value);
extern void reset_inputdevice_config (struct uae_prefs *pr);
extern int inputdevice_joyport_config (struct uae_prefs *p, TCHAR *value, int portnum, int mode, int type);
extern int inputdevice_getjoyportdevice (int port, int val);
......
#define ROMTYPE_KICK 1
#define ROMTYPE_KICKCD32 2
#define ROMTYPE_EXTCD32 4
#define ROMTYPE_EXTCDTV 8
#define ROMTYPE_A2091BOOT 16
#define ROMTYPE_A4091BOOT 32
#define ROMTYPE_AR 64
#define ROMTYPE_SUPERIV 128
#define ROMTYPE_KEY 256
#define ROMTYPE_ARCADIABIOS 512
#define ROMTYPE_ARCADIAGAME 1024
#define ROMTYPE_HRTMON 2048
struct romheader {
char *name;
int id;
};
/* Mask to determine CPU type required by the ROM. */
#define ROMREQ_CPUMASK 3
#define ROMREQ_68EC020 1
#define ROMREQ_68020 2
#define ROMREQ_68030 3
#define ROMREQ_A4000MB 4
#define ROMREQ_A4000 (ROMREQ_A4000MB | ROMREQ_68020)
#define ROMREQ_A1000 8
struct romdata {
char *name;
int ver, rev;
int subver, subrev;
char *model;
uae_u32 size;
int id;
int cpu;
int cloanto;
int type;
int title;
uae_u32 crc32;
uae_u32 sha1[5];
char *configname;
};
/* Used to tag a romlist elt with the location where it was found.
That way, we can quickly remove everything from a user path when
that changes, leaving the system ROMs intact. */
#define ROMLOC_SYSTEM 1
#define ROMLOC_USER 2
struct romlist {
char *path;
struct romdata *rd;
int loc;
};
extern struct romdata *getromdatabycrc (uae_u32 crc32);
extern struct romdata *getromdatabydata (uae_u8 *rom, int size);
extern struct romdata *getromdatabyid (int id);
extern struct romdata *getarcadiarombyname (char *name);
extern void getromname (struct romdata*, char*);
extern struct romdata *getromdatabyname (char*);
extern void romlist_add (char *path, struct romdata *rd, int loc);
extern char *romlist_get (struct romdata *rd);
extern void romlist_clear (int mask);
extern int decode_cloanto_rom (uae_u8 *, int, int, int);
extern struct romlist *romlist_from_idx (int idx, int type, int need_crc32);
extern void scan_roms (const char *path, int loc);
......@@ -24,6 +24,10 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
#define ROMTYPE_CD32 0x200000
#define ROMTYPE_SCRAMBLED 0x400000
#define ROMTYPE_ALL_KICK (ROMTYPE_KICK | ROMTYPE_KICKCD32 | ROMTYPE_CD32)
#define ROMTYPE_ALL_EXT (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV)
#define ROMTYPE_ALL_CART (ROMTYPE_AR | ROMTYPE_HRTMON | ROMTYPE_NORDIC | ROMTYPE_XPOWER | ROMTYPE_CD32CART)
struct romheader {
TCHAR *name;
int id;
......@@ -60,7 +64,7 @@ extern struct romdata *getromdatabyidgroup (int id, int group, int subitem);
//extern struct romdata *getromdatabyzfile (struct zfile *f);
extern struct romlist **getarcadiaroms (void);
extern struct romdata *getarcadiarombyname (const TCHAR *name);
extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int all);
extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all);
extern void getromname (const struct romdata*, TCHAR*);
//extern struct romdata *getromdatabyname (const TCHAR*);
extern struct romlist *getromlistbyids (const int *ids);
......
......@@ -982,12 +982,13 @@ static struct inputevent *readevent (TCHAR *name, TCHAR **customp)
return &events[0];
}
void read_inputdevice_config (struct uae_prefs *pr, TCHAR *option, TCHAR *value)
void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *value)
{
struct uae_input_device *id = 0;
struct inputevent *ie;
int devnum, num, button, joystick, subnum, idnum, keynum;
TCHAR *p, *p2, *custom;
const TCHAR *p;
TCHAR *p2, *custom;
option += 6; /* "input." */
p = getstring (&option);
......@@ -2116,12 +2117,13 @@ static void cap_check (void)
int isbutton = getbuttonstate (joy, i == 0 ? JOYBUTTON_3 : JOYBUTTON_2);
if (cd32_pad_enabled[joy]) {
if (i == 0) // 3rd button?
continue;
if (cd32padmode (p5dir, p5dat))
continue;
// only red and blue can be read if CD32 pad and only if it is in normal pad mode
isbutton |= getbuttonstate (joy, JOYBUTTON_CD32_BLUE);
// CD32 pad 3rd button line (P5) is always floating
if (i == 0)
isbutton = 0;
if (cd32padmode (p5dir, p5dat))
continue;
}
dong = dongle_analogjoy (joy, i);
......@@ -2176,6 +2178,10 @@ static void cap_check (void)
if (!(potgo_value & pdir) && i == 1 && charge == 0)
charge = 2;
}
// CD32 pad in 2-button mode: blue button is not floating
if (cd32_pad_enabled[joy] && i == 1 && charge == 0)
charge = 2;
/* official Commodore mouse has pull-up resistors in button lines
* NOTE: 3rd party mice may not have pullups! */
if (dong < 0 && (mouse_pullup && mouse_port[joy] && digital_port[joy][i]) && charge == 0)
......@@ -2193,7 +2199,7 @@ static void cap_check (void)
}
uae_u8 handle_joystick_buttons (uae_u8 dra)
uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
{
uae_u8 but = 0;
int i;
......@@ -2204,9 +2210,9 @@ uae_u8 handle_joystick_buttons (uae_u8 dra)
if (cd32_pad_enabled[i]) {
uae_u16 p5dir = 0x0200 << (i * 4);
uae_u16 p5dat = 0x0100 << (i * 4);
but |= 0x40 << i;
but |= mask;
if (!cd32padmode (p5dir, p5dat)) {
if (getbuttonstate (i, JOYBUTTON_CD32_RED))
if (getbuttonstate (i, JOYBUTTON_CD32_RED) || getbuttonstate (i, JOYBUTTON_1))
but &= ~mask;
}
} else {
......@@ -2217,11 +2223,11 @@ uae_u8 handle_joystick_buttons (uae_u8 dra)
if (uaerand () & 1)
but |= mask;
}
if (dra & mask)
but = (but & ~mask) | (pra & mask);
}
}
if (inputdevice_logging & 4)
write_log ("BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC);
return but;
......@@ -2878,10 +2884,17 @@ int handle_input_event (int nr, int state, int max, int autofire)
if (ie->type & 4) {
int old = joybutton[joy] & (1 << ie->data);
if (state)
if (state) {
joybutton[joy] |= 1 << ie->data;
else
#ifdef RETROPLATFORM
rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 1);
#endif
} else {
joybutton[joy] &= ~(1 << ie->data);
#ifdef RETROPLATFORM
rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 0);
#endif
}
if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
// emulate contact bounce, 1st button only, others have capacitors
......@@ -3013,7 +3026,12 @@ int handle_input_event (int nr, int state, int max, int autofire)
joydir[joy] |= DIR_UP;
if (bot)
joydir[joy] |= DIR_DOWN;
#ifdef RETROPLATFORM
rp_update_gameport (joy, RP_JOYSTICK_LEFT, left);
rp_update_gameport (joy, RP_JOYSTICK_RIGHT, right);
rp_update_gameport (joy, RP_JOYSTICK_DOWN, bot);
rp_update_gameport (joy, RP_JOYSTICK_UP, top);
#endif
}
break;
case 0: /* ->KEY */
......@@ -4504,6 +4522,8 @@ void inputdevice_updateconfig (struct uae_prefs *prefs)
rp_input_change (1);
rp_input_change (2);
rp_input_change (3);
for (i = 0; i < MAX_JPORTS; i++)
rp_update_gameport (i, -1, 0);
#endif
joybutton[0] = joybutton[1] = 0;
......@@ -5526,7 +5546,7 @@ void setjoystickstate (int joy, int axis, int state, int max)
return;
}
for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i]);
handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i] & ID_FLAG_AUTOFIRE);
id2->states[axis] = state;
}
int getjoystickstate (int joy)
......
......@@ -62,116 +62,15 @@ static int data_in_serdatr; /* new data received */
// --- dinput.cpp START ---
int rawkeyboard = -1;
int no_rawinput;
// --- dinput.cpp END -----
static uae_u32 REGPARAM2 gfxmem_lgetx (uaecptr addr)
{
uae_u32 *m;
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
m = (uae_u32 *)(gfxmemory + addr);
return do_get_mem_long (m);
}
static uae_u32 REGPARAM2 gfxmem_wgetx (uaecptr addr)
{
uae_u16 *m;
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
m = (uae_u16 *)(gfxmemory + addr);
return do_get_mem_word (m);
}
static uae_u32 REGPARAM2 gfxmem_bgetx (uaecptr addr)
{
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
return gfxmemory[addr];
}
static void REGPARAM2 gfxmem_lputx (uaecptr addr, uae_u32 l)
{
uae_u32 *m;
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
m = (uae_u32 *)(gfxmemory + addr);
do_put_mem_long (m, l);
}
static void REGPARAM2 gfxmem_wputx (uaecptr addr, uae_u32 w)
{
uae_u16 *m;
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
m = (uae_u16 *)(gfxmemory + addr);
do_put_mem_word (m, (uae_u16)w);
}
static void REGPARAM2 gfxmem_bputx (uaecptr addr, uae_u32 b)
{
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
gfxmemory[addr] = b;
}
static int REGPARAM2 gfxmem_check (uaecptr addr, uae_u32 size)
{
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
return (addr + size) < allocated_gfxmem;
}
static uae_u8 *REGPARAM2 gfxmem_xlate (uaecptr addr)
{
addr -= gfxmem_start & gfxmem_mask;
addr &= gfxmem_mask;
return gfxmemory + addr;
}
addrbank gfxmem_bankx = {
gfxmem_lgetx, gfxmem_wgetx, gfxmem_bgetx,
gfxmem_lputx, gfxmem_wputx, gfxmem_bputx,
gfxmem_xlate, gfxmem_check, NULL, "RTG RAM",
dummy_lgeti, dummy_wgeti, ABFLAG_RAM
};
void getgfxoffset (int *dxp, int *dyp, int *mxp, int *myp)
{
*dxp = 0;
*dyp = 0;
*mxp = 0;
*myp = 0;
/*
int dx, dy;
getfilteroffset (&dx, &dy, mxp, myp);
*dxp = dx;
*dyp = dy;
if (picasso_on) {
dx = picasso_offset_x;
dy = picasso_offset_y;
*mxp = picasso_offset_mx;
*myp = picasso_offset_my;
}
*dxp = dx;
*dyp = dy;
if (currentmode->flags & DM_W_FULLSCREEN) {
if (scalepicasso && screen_is_picasso)
return;
if (usedfilter && !screen_is_picasso)
return;
if (currentmode->fullfill && (currentmode->current_width > currentmode->native_width || currentmode->current_height > currentmode->native_height))
return;
dx += (currentmode->native_width - currentmode->current_width) / 2;
dy += (currentmode->native_height - currentmode->current_height) / 2;
}
*dxp = dx;
*dyp = dy;
*/
*dxp = 0;
*dyp = 0;
*mxp = 0;
*myp = 0;
}
int is_tablet (void)
{
return tablet ? 1 : 0;
......@@ -332,6 +231,7 @@ static int driveclick_fdrawcmd_open_2(int drive)
return 0;
return 1;
*/
return 0;
}
int driveclick_fdrawcmd_open(int drive)
......@@ -342,6 +242,7 @@ int driveclick_fdrawcmd_open(int drive)
driveclick_fdrawcmd_init(drive);
return 1;
*/
return 0;
}
void driveclick_fdrawcmd_detect(void)
......@@ -406,7 +307,7 @@ static int driveclick_fdrawcmd_init(int drive)
uae_u32 emulib_target_getcpurate (uae_u32 v, uae_u32 *low)
{
/*
#ifdef _WIN32
*low = 0;
if (v == 1) {
LARGE_INTEGER pf;
......@@ -421,40 +322,21 @@ uae_u32 emulib_target_getcpurate (uae_u32 v, uae_u32 *low)
*low = pf.LowPart;
return pf.HighPart;
}
*/
return 0;
}
#else
/*
int isfat (uae_u8 *p)
{
int i, b;
static struct timeval _tstart, _tend;
static struct timezone tz;
if ((p[0x15] & 0xf0) != 0xf0)
return 0;
if (p[0x0b] != 0x00 || p[0x0c] != 0x02)
return 0;
b = 0;
for (i = 0; i < 8; i++) {
if (p[0x0d] & (1 << i))
b++;
*low = 0;
if (v == 1) {
gettimeofday (&_tstart, &tz);
} else if (v == 2) {
gettimeofday (&_tend, &tz);
}
if (b != 1)
return 0;
if (p[0x0f] != 0)
return 0;
if (p[0x0e] > 8 || p[0x0e] == 0)
return 0;
if (p[0x10] == 0 || p[0x10] > 8)
return 0;
b = (p[0x12] << 8) | p[0x11];
if (b > 8192 || b <= 0)
return 0;
b = p[0x16] | (p[0x17] << 8);
if (b == 0 || b > 8192)
return 0;
return 1;
}
*/
#endif
}
void setmouseactivexy (int x, int y, int dir)
{
/* int diff = 8;
......@@ -531,11 +413,10 @@ int my_getvolumeinfo (const char *root)
return -1;
if (!S_ISDIR(sonuc.st_mode))
return -1;
//------------
return ret;
}
// --- clipboard.c --- temporary here ---
// clipboard.c
static uaecptr clipboard_data;
static int vdelay, signaling, initialized;
......@@ -744,7 +625,7 @@ uae_u8 *save_log (int bootlog, int *len)
return dst;
}
// --- win32gui.c
// win32gui.c
#define MAX_ROM_PATHS 10
int scan_roms (int show)
{
......@@ -768,7 +649,7 @@ end:
return ret;
}
// -- dinput.c
// dinput.c
int input_get_default_lightpen (struct uae_input_device *uid, int i, int port, int af)
{
/* struct didata *did;
......@@ -962,18 +843,18 @@ void debugger_change (int mode)
// regsetint (NULL, "DebuggerType", debugger_type);
openconsole ();
}
//unicode.c
// unicode.c
char *ua (const TCHAR *s)
{
return s;
}
//keyboard.c
// keyboard.c
void clearallkeys (void)
{
inputdevice_updateconfig (&currprefs);
}
//fsdb_mywin32.c
// fsdb_mywin32.c
FILE *my_opentext (const TCHAR *name)
{
FILE *f;
......
......@@ -503,4 +503,5 @@ void ncr_init (void)
}
map_banks (&ncr_bank, 0xe80000 >> 16, 65536 >> 16, 0);
}
#endif //ncr
\ No newline at end of file
......@@ -379,7 +379,7 @@ static void romlist_cleanup (void)
}
}
struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int all)
struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all)
{
int i, j, ok, out, max;
struct romdata *rd;
......@@ -406,7 +406,7 @@ struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, co
continue;
if (model && !_tcsicmp (model, rd->name))
ok = 2;
if (rd->ver == ver && (rev < 0 || rd->rev == rev)) {
if ((ver < 0 || rd->ver == ver) && (rev < 0 || rd->rev == rev)) {
if (subver >= 0) {
if (rd->subver == subver && (subrev < 0 || rd->subrev == subrev) && rd->subver > 0)
ok = 1;
......@@ -419,7 +419,7 @@ struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, co
if (model && ok < 2) {
TCHAR *p = rd->model;
ok = 0;
while (*p) {
while (p && *p) {
if (!_tcscmp(rd->model, model)) {
ok = 1;
break;
......@@ -427,7 +427,7 @@ struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, co
p = p + _tcslen(p) + 1;
}
}
if (!model && rd->type != ROMTYPE_KICK)
if (romflags && (rd->type & romflags) == 0)
ok = 0;
if (ok) {
if (all) {
......
......@@ -709,7 +709,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
}
}
} else {
io_error = CDERR_NotSpecified;
io_error = IOERR_NotSpecified;
}
}
break;
......@@ -848,7 +848,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
put_long (io_data + 8, diskpos);
io_actual = 12;
} else {
io_error = CDERR_InvalidState;
io_error = IOERR_InvalidState;
}
} else {
io_error = IOERR_BADADDRESS;
......@@ -1006,7 +1006,7 @@ static uae_u32 REGPARAM2 dev_abortio (TrapContext *context)
}
put_byte (request + 31, IOERR_ABORTED);
if (log_scsi)
write_log ("abortio %s unit=%d, request=%08.8X\n", getdevname (pdev->type), pdev->unit, request);
write_log ("abortio %s unit=%d, request=%08X\n", getdevname (pdev->type), pdev->unit, request);
abort_async (dev, request, IOERR_ABORTED, 0);
return 0;
}
......
......@@ -445,7 +445,7 @@ configure:4344: $? = 0
configure:4344: result: yes
configure:4350: checking for _doprnt
configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/cca25XDN.o: In function `main':
/tmp/ccfiu6rL.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt'
collect2: ld returned 1 exit status
configure:4350: $? = 1
......@@ -533,7 +533,7 @@ configure:4364: $? = 0
configure:4364: result: yes
configure:4364: checking for strcmpi
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/ccfgVok2.o: In function `main':
/tmp/ccbxgm14.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi'
collect2: ld returned 1 exit status
configure:4364: $? = 1
......@@ -613,7 +613,7 @@ configure: failed program was:
configure:4364: result: no
configure:4364: checking for stricmp
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/ccY0iee7.o: In function `main':
/tmp/cc9wD849.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp'
collect2: ld returned 1 exit status
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