Several fixes for regressions (Innocent until caught and curse of enchantia), Add fix for mechwarrior.)
lowered eoi timeout to 0.06f. (ripsaw, Srecko and h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3791
This commit is contained in:
parent
41729e0ca5
commit
d95950242d
1 changed files with 39 additions and 16 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2011 The DOSBox Team
|
||||
* Copyright (C) 2002-2012 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,12 +30,15 @@ bool MIDI_Available(void);
|
|||
|
||||
static void MPU401_Event(Bitu);
|
||||
static void MPU401_Reset(void);
|
||||
static void MPU401_EOIHandler(void);
|
||||
static void MPU401_ResetDone(Bitu);
|
||||
static void MPU401_EOIHandler(Bitu val=0);
|
||||
static void MPU401_EOIHandlerDispatch(void);
|
||||
|
||||
#define MPU401_VERSION 0x15
|
||||
#define MPU401_REVISION 0x01
|
||||
#define MPU401_QUEUE 32
|
||||
#define MPU401_TIMECONSTANT (60000000/1000.0f)
|
||||
#define MPU401_RESETBUSY 27.0f
|
||||
|
||||
enum MpuMode { M_UART,M_INTELLIGENT };
|
||||
enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND};
|
||||
|
@ -72,8 +75,9 @@ static struct {
|
|||
bool wsd,wsm,wsd_start;
|
||||
bool run_irq,irq_pending;
|
||||
bool send_now;
|
||||
bool eoi_scheduled;
|
||||
Bits data_onoff;
|
||||
Bitu command_byte;
|
||||
Bitu command_byte,cmd_pending;
|
||||
Bit8u tmask,cmask,amask;
|
||||
Bit16u midi_mask;
|
||||
Bit16u req_mask;
|
||||
|
@ -112,12 +116,13 @@ static void ClrQueue(void) {
|
|||
|
||||
static Bitu MPU401_ReadStatus(Bitu port,Bitu iolen) {
|
||||
Bit8u ret=0x3f; /* Bits 6 and 7 clear */
|
||||
if (mpu.state.cmd_pending) ret|=0x40;
|
||||
if (!mpu.queue_used) ret|=0x80;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) {
|
||||
mpu.state.reset=0;
|
||||
if (mpu.state.reset) {mpu.state.cmd_pending=val+1;return;}
|
||||
if (val<=0x2f) {
|
||||
switch (val&3) { /* MIDI stop, start, continue */
|
||||
case 1: {MIDI_RawOutByte(0xfc);break;}
|
||||
|
@ -239,12 +244,10 @@ static void MPU401_WriteCommand(Bitu port,Bitu val,Bitu iolen) {
|
|||
break;
|
||||
case 0xff: /* Reset MPU-401 */
|
||||
LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val);
|
||||
mpu.state.reset=1;
|
||||
if (CPU_Cycles > 5) { //It came from the desert wants a fast irq
|
||||
CPU_CycleLeft += CPU_Cycles;
|
||||
CPU_Cycles = 5;
|
||||
}
|
||||
PIC_AddEvent(MPU401_ResetDone,MPU401_RESETBUSY);
|
||||
mpu.state.reset=true;
|
||||
MPU401_Reset();
|
||||
if (mpu.mode==M_UART) return;//do not send ack in UART mode
|
||||
break;
|
||||
case 0x3f: /* UART mode */
|
||||
LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val);
|
||||
|
@ -284,7 +287,7 @@ static Bitu MPU401_ReadData(Bitu port,Bitu iolen) {
|
|||
}
|
||||
if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) {
|
||||
mpu.state.data_onoff=-1;
|
||||
MPU401_EOIHandler();
|
||||
MPU401_EOIHandlerDispatch();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -390,7 +393,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) {
|
|||
if (val<0xf0) mpu.state.data_onoff++;
|
||||
else {
|
||||
mpu.state.data_onoff=-1;
|
||||
MPU401_EOIHandler();
|
||||
MPU401_EOIHandlerDispatch();
|
||||
return;
|
||||
}
|
||||
if (val==0) mpu.state.send_now=true;
|
||||
|
@ -402,13 +405,13 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) {
|
|||
if (val==0xf8 || val==0xf9) mpu.condbuf.type=T_OVERFLOW;
|
||||
mpu.condbuf.value[mpu.condbuf.vlength]=val;
|
||||
mpu.condbuf.vlength++;
|
||||
if ((val&0xf0)!=0xe0) MPU401_EOIHandler();
|
||||
if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch();
|
||||
else mpu.state.data_onoff++;
|
||||
break;
|
||||
case 2:/* Command byte #2 */
|
||||
mpu.condbuf.value[mpu.condbuf.vlength]=val;
|
||||
mpu.condbuf.vlength++;
|
||||
MPU401_EOIHandler();
|
||||
MPU401_EOIHandlerDispatch();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -420,7 +423,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) {
|
|||
if (val<0xf0) mpu.state.data_onoff=1;
|
||||
else {
|
||||
mpu.state.data_onoff=-1;
|
||||
MPU401_EOIHandler();
|
||||
MPU401_EOIHandlerDispatch();
|
||||
return;
|
||||
}
|
||||
if (val==0) mpu.state.send_now=true;
|
||||
|
@ -461,7 +464,7 @@ static void MPU401_WriteData(Bitu port,Bitu val,Bitu iolen) {
|
|||
}
|
||||
}
|
||||
if (!(posd==1 && val>=0xf0)) mpu.playbuf[mpu.state.channel].value[posd-1]=val;
|
||||
if (posd==length) MPU401_EOIHandler();
|
||||
if (posd==length) MPU401_EOIHandlerDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,7 +543,18 @@ next_event:
|
|||
PIC_AddEvent(MPU401_Event,MPU401_TIMECONSTANT/new_time);
|
||||
}
|
||||
|
||||
static void MPU401_EOIHandler(void) {
|
||||
|
||||
static void MPU401_EOIHandlerDispatch(void) {
|
||||
if (mpu.state.send_now) {
|
||||
mpu.state.eoi_scheduled=true;
|
||||
PIC_AddEvent(MPU401_EOIHandler,0.06f); //Possible a bit longer
|
||||
}
|
||||
else if (!mpu.state.eoi_scheduled) MPU401_EOIHandler();
|
||||
}
|
||||
|
||||
//Updates counters and requests new data on "End of Input"
|
||||
static void MPU401_EOIHandler(Bitu val) {
|
||||
mpu.state.eoi_scheduled=false;
|
||||
if (mpu.state.send_now) {
|
||||
mpu.state.send_now=false;
|
||||
if (mpu.state.cond_req) UpdateConductor();
|
||||
|
@ -558,9 +572,18 @@ static void MPU401_EOIHandler(void) {
|
|||
} while ((i++)<16);
|
||||
}
|
||||
|
||||
static void MPU401_ResetDone(Bitu) {
|
||||
mpu.state.reset=false;
|
||||
if (mpu.state.cmd_pending) {
|
||||
MPU401_WriteCommand(0x331,mpu.state.cmd_pending-1,1);
|
||||
mpu.state.cmd_pending=0;
|
||||
}
|
||||
}
|
||||
static void MPU401_Reset(void) {
|
||||
PIC_DeActivateIRQ(mpu.irq);
|
||||
mpu.mode=(mpu.intelligent ? M_INTELLIGENT : M_UART);
|
||||
PIC_RemoveEvents(MPU401_EOIHandler);
|
||||
mpu.state.eoi_scheduled=false;
|
||||
mpu.state.wsd=false;
|
||||
mpu.state.wsm=false;
|
||||
mpu.state.conductor=false;
|
||||
|
|
Loading…
Add table
Reference in a new issue