Пример #1
0
/**
 * Handle word read access from IO memory.
 */
uae_u32 IoMem_wget(uaecptr addr)
{
	Uint32 idx;
	Uint16 val;

	/* Check if access is made by a new instruction or by the same instruction doing multiple word accesses */
	if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter )
		IoAccessInstrCount++;			/* Same instruction, increase access count */
	else
	{
		IoAccessInstrPrevClock = CyclesGlobalClockCounter;
		if ( ( table68k[ M68000_CurrentOpcode ].size == 1 )
		  && ( OpcodeFamily != i_MVMEL ) && ( OpcodeFamily != i_MVMLE ) )
			IoAccessInstrCount = 0;		/* Instruction size is word and not a movem : no multiple accesses */
		else
			IoAccessInstrCount = 1;		/* 1st access of a long or movem.w */
	}

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
		return -1;
	}
	if (addr > 0xfffffe)
	{
		fprintf(stderr, "Illegal IO memory access: IoMem_wget($%x)\n", addr);
		return -1;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame */
	nIoMemAccessSize = SIZE_WORD;
	nBusErrorAccesses = 0;
	idx = addr - 0xff8000;

	IoAccessCurrentAddress = addr;
	pInterceptReadTable[idx]();                   /* Call 1st handler */

	if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
	{
		IoAccessCurrentAddress = addr + 1;
		pInterceptReadTable[idx+1]();             /* Call 2nd handler */
	}

	/* Check if we completely read from a bus-error region */
	if (nBusErrorAccesses == 2)
	{
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
		return -1;
	}

	val = IoMem_ReadWord(addr);

	LOG_TRACE(TRACE_IOMEM_RD, "IO read.w $%06x = $%04x pc=%x\n", addr, val, M68000_GetPC());

	return val;
}
Пример #2
0
/**
 * Write word to sound control register (0xff8900).
 *
 * FIXME: add Falcon specific handler here...
 */
void DmaSnd_SoundControl_WriteWord(void)
{
	Uint16 nNewSndCtrl;

	HATARI_TRACE(HATARI_TRACE_DMASND, "DMA snd control write: 0x%04x\n", IoMem_ReadWord(0xff8900));

	nNewSndCtrl = IoMem_ReadWord(0xff8900) & 3;

	if (!(nDmaSoundControl & DMASNDCTRL_PLAY) && (nNewSndCtrl & DMASNDCTRL_PLAY))
	{
		//fprintf(stderr, "Turning on DMA sound emulation.\n");
		DmaSnd_StartNewFrame();
	}
	else if ((nDmaSoundControl & DMASNDCTRL_PLAY) && !(nNewSndCtrl & DMASNDCTRL_PLAY))
	{
		//fprintf(stderr, "Turning off DMA sound emulation.\n");
	}

	nDmaSoundControl = nNewSndCtrl;
}
Пример #3
0
/**
 * Handle word read access from IO memory.
 */
uae_u32 IoMem_wget(uaecptr addr)
{
	Uint32 idx;
	Uint16 val;

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_READ);
		return -1;
	}
	if (addr > 0xfffffe)
	{
		fprintf(stderr, "Illegal IO memory access: IoMem_wget($%x)\n", addr);
		return -1;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame */
	nIoMemAccessSize = SIZE_WORD;
	nBusErrorAccesses = 0;
	idx = addr - 0xff8000;

	IoAccessCurrentAddress = addr;
	pInterceptReadTable[idx]();                   /* Call 1st handler */

	if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
	{
		IoAccessCurrentAddress = addr + 1;
		pInterceptReadTable[idx+1]();             /* Call 2nd handler */
	}

	/* Check if we completely read from a bus-error region */
	if (nBusErrorAccesses == 2)
	{
		M68000_BusError(addr, BUS_ERROR_READ);
		return -1;
	}

	val = IoMem_ReadWord(addr);

	LOG_TRACE(TRACE_IOMEM_RD, "IO read.w $%06x = $%04x\n", addr, val);

	return val;
}
Пример #4
0
/**
 * Handle word read access from IO memory.
 */
uae_u32 IoMem_wget(uaecptr addr)
{
	Uint32 idx;
	Uint16 val;


	if ((addr & IO_SEG_MASK) >= IO_SIZE)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_READ);
		return -1;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame */
	nIoMemAccessSize = SIZE_WORD;
	nBusErrorAccesses = 0;
	idx = addr & IO_SEG_MASK;

	IoAccessCurrentAddress = addr;
	pInterceptReadTable[idx]();                   /* Call 1st handler */

	if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
	{
		IoAccessCurrentAddress = addr + 1;
		pInterceptReadTable[idx+1]();             /* Call 2nd handler */
	}

	/* Check if we completely read from a bus-error region */
	if (nBusErrorAccesses == 2)
	{
		M68000_BusError(addr, BUS_ERROR_READ);
		return -1;
	}

	val = IoMem_ReadWord(addr);

	LOG_TRACE(TRACE_IOMEM_RD, "IO read.w $%06x = $%04x\n", addr, val);

	return val;
}
Пример #5
0
/**
 * Mix DMA sound sample with the normal PSG sound samples.
 */
void DmaSnd_GenerateSamples(int nMixBufIdx, int nSamplesToGenerate)
{
	double FreqRatio;
	int i;
	int nBufIdx;
	Sint8 *pFrameStart;

	if (ConfigureParams.System.nMachineType == MACHINE_FALCON
	    && (IoMem_ReadWord(0xff8932) & 0x6000) == 0x2000)
	{
		DmaSnd_GenerateDspSamples(nMixBufIdx, nSamplesToGenerate);
		return;
	}

	if (!(nDmaSoundControl & DMASNDCTRL_PLAY))
		return;

	pFrameStart = (Sint8 *)&STRam[nFrameStartAddr];
	FreqRatio = DmaSnd_DetectSampleRate() / (double)nAudioFrequency;

	if (ConfigureParams.System.nMachineType == MACHINE_FALCON
	    && (nDmaSoundMode & DMASNDMODE_16BITSTEREO))
	{
		/* Stereo 16-bit */
		FreqRatio *= 4.0;
		for (i = 0; i < nSamplesToGenerate; i++)
		{
			nBufIdx = (nMixBufIdx + i) % MIXBUFFER_SIZE;
			MixBuffer[nBufIdx][0] = ((int)MixBuffer[nBufIdx][0]
			                        + (int)(*(Sint16*)&pFrameStart[((int)FrameCounter)&~1])) / 2;
			MixBuffer[nBufIdx][1] = ((int)MixBuffer[nBufIdx][1]
			                        + (int)(*(Sint16*)&pFrameStart[(((int)FrameCounter)&~1)+2])) / 2;
			FrameCounter += FreqRatio;
			if (DmaSnd_CheckForEndOfFrame(FrameCounter))
				break;
		}
	}
	else if (nDmaSoundMode & DMASNDMODE_MONO)  /* 8-bit stereo or mono? */
	{
		/* Mono 8-bit */
		for (i = 0; i < nSamplesToGenerate; i++)
		{
			nBufIdx = (nMixBufIdx + i) % MIXBUFFER_SIZE;
			MixBuffer[nBufIdx][0] = MixBuffer[nBufIdx][1] =
				((int)MixBuffer[nBufIdx][0] + (((int)pFrameStart[(int)FrameCounter]) << 8)) / 2;
			FrameCounter += FreqRatio;
			if (DmaSnd_CheckForEndOfFrame(FrameCounter))
				break;
		}
	}
	else
	{
		/* Stereo 8-bit */
		FreqRatio *= 2.0;
		for (i = 0; i < nSamplesToGenerate; i++)
		{
			nBufIdx = (nMixBufIdx + i) % MIXBUFFER_SIZE;
			MixBuffer[nBufIdx][0] = ((int)MixBuffer[nBufIdx][0]
			                        + (((int)pFrameStart[((int)FrameCounter)&~1]) << 8)) / 2;
			MixBuffer[nBufIdx][1] = ((int)MixBuffer[nBufIdx][1]
			                        + (((int)pFrameStart[(((int)FrameCounter)&~1)+1]) << 8)) / 2;
			FrameCounter += FreqRatio;
			if (DmaSnd_CheckForEndOfFrame(FrameCounter))
				break;
		}
	}
}