Пример #1
0
/**
 * Check if end-of-frame has been reached and raise interrupts if needed.
 * Returns TRUE if DMA sound processing should be stopped now and FALSE
 * if it continues.
 */
static inline int DmaSnd_CheckForEndOfFrame(int nFrameCounter)
{
	if (nFrameCounter >= nFrameLen)
	{
		/* Raise end-of-frame interrupts (MFP-i7 and Time-A) */
		MFP_InputOnChannel(MFP_TIMER_GPIP7_BIT, MFP_IERA, &MFP_IPRA);
		if (MFP_TACR == 0x08)       /* Is timer A in Event Count mode? */
			MFP_TimerA_EventCount_Interrupt();

		if (nDmaSoundControl & DMASNDCTRL_PLAYLOOP)
		{
			DmaSnd_StartNewFrame();
		}
		else
		{
			nDmaSoundControl &= ~DMASNDCTRL_PLAY;
			return TRUE;
		}
	}

	return FALSE;
}
Пример #2
0
/**
 * Write byte to YM's register (0xff8802), store according to PSG select register (0xff8800)
 */
void PSG_Set_DataRegister(Uint8 val)
{
	if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym write data reg=0x%x val=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
		                PSGRegisterSelect, val, FrameCycles, LineCycles,
		                HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
	}

	/* Is a valid PSG register currently selected ? */
	if ( PSGRegisterSelect >= MAX_PSG_REGISTERS )
		return;					/* not valid, ignore write and do nothing */

	/* Create samples up until this point with current values */
	Sound_Update(false);

	/* When a read is made from $ff8800 without changing PSGRegisterSelect, we should return */
	/* the non masked value. */
	PSGRegisterReadData = val;			/* store non masked value for PSG_Get_DataRegister */

	/* Copy value to PSGRegisters[] */
	PSGRegisters[PSGRegisterSelect] = val;

	/* Clear unused bits for some regs */
	if ( ( PSGRegisterSelect == PSG_REG_CHANNEL_A_COARSE ) || ( PSGRegisterSelect == PSG_REG_CHANNEL_B_COARSE )
		|| ( PSGRegisterSelect == PSG_REG_CHANNEL_C_COARSE ) || ( PSGRegisterSelect == PSG_REG_ENV_SHAPE ) )
	  PSGRegisters[PSGRegisterSelect] &= 0x0f;	/* only keep bits 0 - 3 */

	else if ( ( PSGRegisterSelect == PSG_REG_CHANNEL_A_AMP ) || ( PSGRegisterSelect == PSG_REG_CHANNEL_B_AMP )
		|| ( PSGRegisterSelect == PSG_REG_CHANNEL_C_AMP ) || ( PSGRegisterSelect == PSG_REG_NOISE_GENERATOR ) )
	  PSGRegisters[PSGRegisterSelect] &= 0x1f;	/* only keep bits 0 - 4 */


	if ( PSGRegisterSelect < NUM_PSG_SOUND_REGISTERS )
	{
		/* Copy sound related registers 0..13 to the sound module's internal buffer */
		Sound_WriteReg ( PSGRegisterSelect , PSGRegisters[PSGRegisterSelect] );
	}

	else if ( PSGRegisterSelect == PSG_REG_IO_PORTA )
	{
	/*
	 * FIXME: This is only a prelimary dirty hack!
	 * Port B (Printer port) - writing here needs to be dispatched to the printer
	 * STROBE (Port A bit5) does a short LOW and back to HIGH when the char is valid
	 * To print you need to write the character byte to IOB and you need to toggle STROBE
	 * (like EmuTOS does).
	 */
		/* Printer dispatching only when printing is activated */
		if (ConfigureParams.Printer.bEnablePrinting)
		{
			/* Bit 5 - Centronics strobe? If STROBE is low and the LastStrobe was high,
					then print/transfer to the emulated Centronics port.
			 */
			if (LastStrobe && ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<5)) == 0 ))
			{
				/* Seems like we want to print something... */
				Printer_TransferByteTo(PSGRegisters[PSG_REG_IO_PORTB]);
				/* Initiate a possible GPIP0 Printer BUSY interrupt */
				MFP_InputOnChannel ( MFP_INT_GPIP0 , 0 );
				/* Initiate a possible GPIP1 Falcon ACK interrupt */
				if (ConfigureParams.System.nMachineType == MACHINE_FALCON)
					MFP_InputOnChannel ( MFP_INT_GPIP1 , 0 );
			}
		}
		LastStrobe = PSGRegisters[PSG_REG_IO_PORTA]&(1<<5);

		/* Bit 0-2 : side and drive select */
		if ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<1)) == 0 )
		{
			/* floppy drive A is ON */
			Statusbar_SetFloppyLed(DRIVE_LED_A, LED_STATE_ON);
		}
		else
		{
			Statusbar_SetFloppyLed(DRIVE_LED_A, LED_STATE_OFF);
		}
		if ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<2)) == 0 )
		{
			/* floppy drive B is ON */
			Statusbar_SetFloppyLed(DRIVE_LED_B, LED_STATE_ON);
		}
		else
		{
			Statusbar_SetFloppyLed(DRIVE_LED_B, LED_STATE_OFF);
		}

		/* Bit 3 - Centronics as input */
		if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<3))
		{
			/* FIXME: might be needed if we want to emulate sound sampling hardware */
		}
		
		/* handle Falcon specific bits in PORTA of the PSG */
		if (ConfigureParams.System.nMachineType == MACHINE_FALCON)
		{
			/* Bit 4 - DSP reset? */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<4))
			{
				Log_Printf(LOG_DEBUG, "Calling DSP_Reset?\n");
#if ENABLE_DSP_EMU
				if (ConfigureParams.System.nDSPType == DSP_TYPE_EMU) {
					DSP_Reset();
				}
#endif
			}
			/* Bit 6 - Internal Speaker control */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<6))
			{
				/*Log_Printf(LOG_DEBUG, "Falcon: Internal Speaker state\n");*/
				/* FIXME: add code to handle? (if we want to emulate the speaker at all? */
			}
			/* Bit 7 - Reset IDE? */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<7))
			{
				Log_Printf(LOG_DEBUG, "Falcon: Reset IDE subsystem\n");
				/* FIXME: add code to handle IDE reset */
			}
		}
	
	}
}