コード例 #1
0
ファイル: svm32.c プロジェクト: drudru/cel
void init (VM32Cpu * cpu) 
{
	VMReset(cpu);
	cpu->breakHook    = DefaultBreak;
	cpu->invalidHook  = DefaultInvalidInstruction;
	cpu->argCountHook = DefaultInvalidArgCount;
	cpu->pushHook     = NULL;
	cpu->activateHook = NULL;
}
コード例 #2
0
/*----------------------------------------------------------------------------
 * ProcessSysExMessage()
 *----------------------------------------------------------------------------
 * Purpose: 
 * Process a SysEx character byte from the MIDI stream. Since we cannot
 * simply wait for the next character to arrive, we are forced to save
 * state after each character. It would be easier to parse at the file
 * level, but then we lose the nice feature of being able to support
 * these messages in a real-time MIDI stream.
 *
 * Inputs:
 * pEASData			- pointer to synthesizer instance data
 * c				- character to be processed
 * locating			- if true, the sequencer is relocating to a new position
 *		
 * Outputs:
 * 
 *
 * Side Effects:
 *
 * Notes:
 * These are the SysEx messages we can receive:
 * 
 * SysEx messages
 * { f0 7e 7f 09 01 f7 } GM 1 On
 * { f0 7e 7f 09 02 f7 } GM 1/2 Off
 * { f0 7e 7f 09 03 f7 } GM 2 On
 * { f0 7f 7f 04 01 lsb msb } Master Volume
 * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
 * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
 *
 *----------------------------------------------------------------------------
*/
static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
{

	/* check for start byte */
	if (c == 0xf0)
	{
		pMIDIStream->sysExState = eSysEx;
	}
	/* check for end byte */
	else if (c == 0xf7)
	{
		/* if this was a MIP message, update the MIP table */
		if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
			VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
		pMIDIStream->sysExState = eSysExIgnore;
	}

	/* process SysEx message */
	else
	{
		switch (pMIDIStream->sysExState)
		{
		case eSysEx:

			/* first byte, determine message class */
			switch (c)
			{
			case 0x7e:
				pMIDIStream->sysExState = eSysExUnivNonRealTime;
				break;
			case 0x7f:
				pMIDIStream->sysExState = eSysExUnivRealTime;
				break;
			case 0x00:
				pMIDIStream->sysExState = eSysExMfgID1;
				break;
			default:
				pMIDIStream->sysExState = eSysExIgnore;
				break;
			}
			break;

		/* process GM message */
		case eSysExUnivNonRealTime:
			if (c == 0x7f)
				pMIDIStream->sysExState = eSysExUnivNrtTargetID;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		case eSysExUnivNrtTargetID:
			if (c == 0x09)
				pMIDIStream->sysExState = eSysExGMControl;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
				
		case eSysExGMControl:
			if ((c == 1) || (c == 3))
			{
				/* GM 1 or GM2 On, reset synth */
				if (parserMode != eParserModeMetaData)
				{
					pMIDIStream->flags |= MIDI_FLAG_GM_ON;
					VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
					VMInitMIPTable(pSynth);
				}
				pMIDIStream->sysExState = eSysExEOX;
			}
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;

		/* Process Master Volume and SP-MIDI */
		case eSysExUnivRealTime:
			if (c == 0x7f)
				pMIDIStream->sysExState = eSysExUnivRtTargetID;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;

		case eSysExUnivRtTargetID:
			if (c == 0x04)
				pMIDIStream->sysExState = eSysExDeviceControl;
			else if (c == 0x0b)
				pMIDIStream->sysExState = eSysExSPMIDI;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		/* process master volume */
		case eSysExDeviceControl:
			if (c == 0x01)
				pMIDIStream->sysExState = eSysExMasterVolume;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		case eSysExMasterVolume:
			/* save LSB */
			pMIDIStream->d1 = c;
			pMIDIStream->sysExState = eSysExMasterVolLSB;
			break;
			
		case eSysExMasterVolLSB:
			if (parserMode != eParserModeMetaData)
			{
				EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
				gain = (gain * gain) >> 15;
				VMSetVolume(pSynth, (EAS_U16) gain);
			}
			pMIDIStream->sysExState = eSysExEOX;
			break;

		/* process SP-MIDI MIP message */
		case eSysExSPMIDI:
			if (c == 0x01)
			{
				/* assume all channels are muted */
				if (parserMode != eParserModeMetaData)
					VMInitMIPTable(pSynth);
				pMIDIStream->d1 = 0;
				pMIDIStream->sysExState = eSysExSPMIDIchan;
			}
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;

		case eSysExSPMIDIchan:
			if (c < NUM_SYNTH_CHANNELS)
			{
				pMIDIStream->d2 = c;
				pMIDIStream->sysExState = eSysExSPMIDIMIP;
			}
			else
			{
				/* bad MIP message - unmute channels */
				if (parserMode != eParserModeMetaData)
					VMInitMIPTable(pSynth);
				pMIDIStream->sysExState = eSysExIgnore;
			}
			break;

		case eSysExSPMIDIMIP:
			/* process MIP entry here */
			if (parserMode != eParserModeMetaData)
				VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
			pMIDIStream->sysExState = eSysExSPMIDIchan;

			/* if 16 channels received, update MIP table */
			if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
			{
				if (parserMode != eParserModeMetaData)
					VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
				pMIDIStream->sysExState = eSysExEOX;
			}
			break;

		/* process Enhancer */
		case eSysExMfgID1:
			if (c == 0x01)
				pMIDIStream->sysExState = eSysExMfgID1;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;

		case eSysExMfgID2:
			if (c == 0x3a)
				pMIDIStream->sysExState = eSysExMfgID1;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		case eSysExMfgID3:
			if (c == 0x04)
				pMIDIStream->sysExState = eSysExEnhancer;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;

		case eSysExEnhancer:
			if (c == 0x01)
				pMIDIStream->sysExState = eSysExEnhancerSubID;
			else
				pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		case eSysExEnhancerSubID:
			pMIDIStream->sysExState = eSysExEnhancerFeedback1;
			break;
			
		case eSysExEnhancerFeedback1:
			pMIDIStream->sysExState = eSysExEnhancerFeedback2;
			break;
			
		case eSysExEnhancerFeedback2:
			pMIDIStream->sysExState = eSysExEnhancerDrive;
			break;
			
		case eSysExEnhancerDrive:
			pMIDIStream->sysExState = eSysExEnhancerWet;
			break;
			
		case eSysExEnhancerWet:
			pMIDIStream->sysExState = eSysExEOX;
			break;
			
		case eSysExEOX:
			{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
			pMIDIStream->sysExState = eSysExIgnore;
			break;
			
		case eSysExIgnore:
			break;
			
		default:
			pMIDIStream->sysExState = eSysExIgnore;
			break;
		}
	}