Sigrid Haflínudóttirfirst dirty version of the portd7ad0686 years agoHistory
868 lines · 19.0 KB · C
RawDownload
/*	ASCEMDEV.c 	Copyright (C) 2008 Paul C. Pratt 	You can redistribute this file and/or modify it under the terms	of version 2 of the GNU General Public License as published by	the Free Software Foundation.  You should have received a copy	of the license along with this file; see the file COPYING. 	This file is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	license for more details.*/ /*	Apple Sound Chip EMulated DEVice*/ #ifndef AllFiles#include "SYSDEPNS.h"#include "ENDIANAC.h"#include "MYOSGLUE.h"#include "EMCONFIG.h"#include "GLOBGLUE.h"#include "VIAEMDEV.h"#endif #include "ASCEMDEV.h" /*	ReportAbnormalID unused 0x0F0E, 0x0F1E - 0x0FFF*/ LOCALVAR ui3r SoundReg801 = 0;LOCALVAR ui3r SoundReg802 = 0;LOCALVAR ui3r SoundReg803 = 0;LOCALVAR ui3r SoundReg804 = 0;LOCALVAR ui3r SoundReg805 = 0;LOCALVAR ui3r SoundReg_Volume = 0; /* 0x806 *//* LOCALVAR ui3r SoundReg807 = 0; */ LOCALVAR ui3b ASC_SampBuff[0x800]; struct ASC_ChanR {	ui3b freq[4];	ui3b phase[4];};typedef struct ASC_ChanR ASC_ChanR; LOCALVAR ASC_ChanR ASC_ChanA[4]; LOCALVAR ui4b ASC_FIFO_Out = 0;LOCALVAR ui4b ASC_FIFO_InA = 0;LOCALVAR ui4b ASC_FIFO_InB = 0;LOCALVAR blnr ASC_Playing = falseblnr; #define ASC_dolog (dbglog_HAVE && 0) #ifdef ASC_interrupt_PulseNtfyIMPORTPROC ASC_interrupt_PulseNtfy(void);#endif LOCALPROC ASC_RecalcStatus(void){	if ((1 == SoundReg801) && ASC_Playing) {		if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200) {			SoundReg804 &= ~ 0x01;		} else {			SoundReg804 |= 0x01;		}		if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400) {			SoundReg804 |= 0x02;		} else {			SoundReg804 &= ~ 0x02;		}		if (0 != (SoundReg802 & 2)) {			if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200) {				SoundReg804 &= ~ 0x04;			} else {				SoundReg804 |= 0x04;			}			if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400) {				SoundReg804 |= 0x08;			} else {				SoundReg804 &= ~ 0x08;			}		}	}} LOCALPROC ASC_ClearFIFO(void){	ASC_FIFO_Out = 0;	ASC_FIFO_InA = 0;	ASC_FIFO_InB = 0;	ASC_Playing = falseblnr;	ASC_RecalcStatus();} GLOBALFUNC ui5b ASC_Access(ui5b Data, blnr WriteMem, CPTR addr){	if (addr < 0x800) {		if (WriteMem) {			if (1 == SoundReg801) {				if (0 == (addr & 0x400)) {					if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400)					{#if 0 /* seems to happen in tetris */						ReportAbnormalID(0x0F01,							"ASC - Channel A Overflow");#endif						SoundReg804 |= 0x02;					} else { 					ASC_SampBuff[ASC_FIFO_InA & 0x3FF] = Data; 					++ASC_FIFO_InA;					if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200)					{						if (0 != (SoundReg804 & 0x01)) {							/* happens normally */							SoundReg804 &= ~ 0x01;						}					} else {#if 0 /* doesn't seem to be necessary, but doesn't hurt either */						SoundReg804 |= 0x01;#endif					}					if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400)					{						SoundReg804 |= 0x02;#if ASC_dolog						dbglog_WriteNote("ASC : setting full flag A");#endif					} else {						if (0 != (SoundReg804 & 0x02)) {							ReportAbnormalID(0x0F02, "ASC_Access : "								"full flag A not already clear");							SoundReg804 &= ~ 0x02;						}					} 					}				} else {					if (0 == (SoundReg802 & 2)) {						ReportAbnormalID(0x0F03,							"ASC - Channel B for Mono");					}					if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400)					{						ReportAbnormalID(0x0F04,							"ASC - Channel B Overflow");						SoundReg804 |= 0x08;					} else { 					ASC_SampBuff[0x400 + (ASC_FIFO_InB & 0x3FF)] = Data; 					++ASC_FIFO_InB;					if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200)					{						if (0 != (SoundReg804 & 0x04)) {							/* happens normally */							SoundReg804 &= ~ 0x04;						}					} else {#if 0 /* doesn't seem to be necessary, but doesn't hurt either */						SoundReg804 |= 0x04;#endif					}					if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400)					{						SoundReg804 |= 0x08;#if ASC_dolog						dbglog_WriteNote("ASC : setting full flag B");#endif					} else {						if (0 != (SoundReg804 & 0x08)) {							ReportAbnormalID(0x0F05, "ASC_Access : "								"full flag B not already clear");							SoundReg804 &= ~ 0x08;						}					} 					}				}#if ASC_dolog && 0				dbglog_writeCStr("ASC_InputIndex =");				dbglog_writeNum(ASC_InputIndex);				dbglog_writeReturn();#endif			} else {				ASC_SampBuff[addr] = Data;			}		} else {			Data = ASC_SampBuff[addr];		} #if ASC_dolog && 1#if 0		if (((addr & 0x1FF) >= 0x04)			&& ((addr & 0x1FF) < (0x200 - 0x04)))		{			/* don't report them all */		} else#endif		{			dbglog_AddrAccess("ASC_Access SampBuff",				Data, WriteMem, addr);		}#endif	} else if (addr < 0x810) {		switch (addr) {			case 0x800: /* VERSION */				if (WriteMem) {					ReportAbnormalID(0x0F06, "ASC - writing VERSION");				} else {					Data = 0;				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (VERSION)",					Data, WriteMem, addr);#endif				break;			case 0x801: /* ENABLE */				if (WriteMem) {					if (1 == Data) {						if (1 != SoundReg801) {							ASC_ClearFIFO();						}					} else {						if (Data > 2) {							ReportAbnormalID(0x0F07,								"ASC - unexpected ENABLE");						}					}					SoundReg801 = Data;				} else {					Data = SoundReg801;					/* happens in LodeRunner */				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (ENABLE)",					Data, WriteMem, addr);#endif				break;			case 0x802: /* CONTROL */				if (WriteMem) {#if 1					if (0 != SoundReg801) {						if (SoundReg802 == Data) {							/*								this happens normally,								such as in Lunar Phantom							*/						} else {							if (1 == SoundReg801) {/*	happens in dark castle, if play other sound first,	such as by changing beep sound in sound control panel.*/								ASC_ClearFIFO();							} #if 0							ReportAbnormalID(0x0F08,								"ASC - changing CONTROL while ENABLEd");#endif						}					}#endif					if (0 != (Data & ~ 2)) {						ReportAbnormalID(0x0F09,							"ASC - unexpected CONTROL value");					}					SoundReg802 = Data;				} else {					Data = SoundReg802;					ReportAbnormalID(0x0F0A,						"ASC - reading CONTROL value");				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (CONTROL)",					Data, WriteMem, addr);#endif				break;			case 0x803:				if (WriteMem) {					if (0 != (Data & ~ 0x80)) {						ReportAbnormalID(0x0F0B,							"ASC - unexpected FIFO MODE");					}					if (0 != (Data & 0x80)) {						if (0 != (SoundReg803 & 0x80)) {							ReportAbnormalID(0x0F0C,								"ASC - set clear FIFO again");						} else						if (1 != SoundReg801) {#if 0 /* happens in system 6, such as with Lunar Phantom */							ReportAbnormalID(0x0F0D,								"ASC - clear FIFO when not FIFO mode");#endif						} else						{							ASC_ClearFIFO();							/*								ASC_interrupt_PulseNtfy();									Doesn't seem to be needed,									but doesn't hurt either.							*/						}					}					SoundReg803 = Data;				} else {					Data = SoundReg803;				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (FIFO MODE)",					Data, WriteMem, addr);#endif				break;			case 0x804:				if (WriteMem) {#if 0					if ((0 != SoundReg804) && (0 != Data)) {						ReportAbnormalID(0x0F0F,							"ASC - set FIFO IRQ STATUS when not 0");					}#endif					SoundReg804 = Data;					if (0 != SoundReg804) {						ASC_interrupt_PulseNtfy();						/*							Generating this interrupt seems							to be the point of writing to							this register.						*/					}#if ASC_dolog && 1					dbglog_AddrAccess(						"ASC_Access Control (FIFO IRQ STATUS)",						Data, WriteMem, addr);#endif				} else {					Data = SoundReg804;#if 0					if (1 != SoundReg801) {						/* no, ok, part of normal interrupt handling */						ReportAbnormalID(0x0F10,							"ASC - read STATUS when not FIFO");					}#endif					/* SoundReg804 = 0; */					SoundReg804 &= ~ 0x01;					SoundReg804 &= ~ 0x04;						/*							In lunar phantom, observe checking							full flag before first write, but							status was read previous.						*/#if ASC_dolog && 1#if 0					if (0 != Data)#endif					{						dbglog_AddrAccess(							"ASC_Access Control (FIFO IRQ STATUS)",							Data, WriteMem, addr);					}#endif				}				break;			case 0x805:				if (WriteMem) {					SoundReg805 = Data;					/* cleared in LodeRunner */				} else {					Data = SoundReg805;					ReportAbnormalID(0x0F11,						"ASC - reading WAVE CONTROL register");				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (WAVE CONTROL)",					Data, WriteMem, addr);#endif				break;			case 0x806: /* VOLUME */				if (WriteMem) {					SoundReg_Volume = Data >> 5;					if (0 != (Data & 0x1F)) {						ReportAbnormalID(0x0F12,							"ASC - unexpected volume value");					}				} else {					Data = SoundReg_Volume << 5;					ReportAbnormalID(0x0F13,						"ASC - reading volume register");				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (VOLUME)",					Data, WriteMem, addr);#endif				break;			case 0x807: /* CLOCK RATE */				if (WriteMem) {					/* SoundReg807 = Data; */					if (0 != Data) {						ReportAbnormalID(0x0F14,							"ASC - nonstandard CLOCK RATE");					}				} else {					/* Data = SoundReg807; */					ReportAbnormalID(0x0F15,						"ASC - reading CLOCK RATE");				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (CLOCK RATE)",					Data, WriteMem, addr);#endif				break;			case 0x808: /* CONTROL */				if (WriteMem) {					ReportAbnormalID(0x0F16, "ASC - write to 808");				} else {					/* happens on boot System 7.5.5 */					Data = 0;				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (CONTROL)",					Data, WriteMem, addr);#endif				break;			case 0x80A: /* ? */				if (WriteMem) {					ReportAbnormalID(0x0F17, "ASC - write to 80A");				} else {					/*						happens in system 6, Lunar Phantom,							soon after new game.					*/					Data = 0;				}#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (80A)",					Data, WriteMem, addr);#endif				break;			default:				if (WriteMem) {				} else {					Data = 0;				}				ReportAbnormalID(0x0F18, "ASC - unknown ASC reg");#if ASC_dolog && 1				dbglog_AddrAccess("ASC_Access Control (?)",					Data, WriteMem, addr);#endif				break;		}	} else if (addr < 0x830) {		ui3r b = addr & 3;		ui3r chan = ((addr - 0x810) >> 3) & 3; 		if (0 != (addr & 4)) { 			if (WriteMem) {				ASC_ChanA[chan].freq[b] = Data;			} else {				Data = ASC_ChanA[chan].freq[b];			}#if ASC_dolog && 1			dbglog_AddrAccess("ASC_Access Control (frequency)",				Data, WriteMem, addr);#endif#if ASC_dolog && 0			dbglog_writeCStr("freq b=");			dbglog_writeNum(WriteMem);			dbglog_writeCStr(", chan=");			dbglog_writeNum(chan);			dbglog_writeReturn();#endif		} else { 			if (WriteMem) {				ASC_ChanA[chan].phase[b] = Data;			} else {				Data = ASC_ChanA[chan].phase[b];			}#if ASC_dolog && 1			dbglog_AddrAccess("ASC_Access Control (phase)",				Data, WriteMem, addr);#endif		}	} else if (addr < 0x838) {#if ASC_dolog && 1		dbglog_AddrAccess("ASC_Access Control *** unknown reg",			Data, WriteMem, addr);#endif	} else {

Lines 1–500 of 868.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t