/* 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. Load more
/* 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_PulseNtfy IMPORTPROC 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 {