diff --git a/Src/C64_Be.h b/Src/C64_Be.h deleted file mode 100644 index aeccb99..0000000 --- a/Src/C64_Be.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * C64_Be.h - Put the pieces together, Be specific stuff - * - * Frodo (C) 1994-1997,2002-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#undef PROFILING - - -/* - * Constructor, system-dependent things - */ - -void C64::c64_ctor1(void) -{ - joy[0] = joy[1] = NULL; - joy_geek_port[0] = joy_geek_port[1] = false; -} - -void C64::c64_ctor2(void) -{ - // Initialize joystick variables - joy_minx = joy_miny = 32767; - joy_maxx = joy_maxy = 0; - - // Initialize semaphores (initially acquired) - pause_sem = create_sem(0, "Frodo Pause Semaphore"); - sound_sync_sem = create_sem(0, "Frodo Sound Sync Semaphore"); - - // Preset speedometer start time - start_time = system_time(); -} - - -/* - * Destructor, system-dependent things - */ - -void C64::c64_dtor(void) -{ - delete_sem(pause_sem); - delete_sem(sound_sync_sem); -} - - -/* - * Start main emulation thread - */ - -void C64::Run(void) -{ - // Reset chips - TheCPU->Reset(); - TheSID->Reset(); - TheCIA1->Reset(); - TheCIA2->Reset(); - TheCPU1541->Reset(); - - // Patch kernal IEC routines - orig_kernal_1d84 = Kernal[0x1d84]; - orig_kernal_1d85 = Kernal[0x1d85]; - PatchKernal(ThePrefs.FastReset, ThePrefs.Emul1541Proc); - - // Start the CPU thread - the_thread = spawn_thread(thread_invoc, "Frodo 6510", B_URGENT_DISPLAY_PRIORITY, this); - thread_running = true; - quit_thyself = false; - have_a_break = false; - resume_thread(the_thread); -} - - -/* - * Stop main emulation thread - */ - -void C64::Quit(void) -{ - long ret; - - // Ask the thread to quit itself if it is running - if (thread_running) { - if (have_a_break) - Resume(); - quit_thyself = true; - wait_for_thread(the_thread, &ret); - thread_running = false; - } -} - - -/* - * Pause main emulation thread - */ - -void C64::Pause(void) -{ - // Ask the thread to pause and wait for acknowledge - if (thread_running && !have_a_break) { - have_a_break = true; - acquire_sem(pause_sem); - TheSID->PauseSound(); - } -} - - -/* - * Resume main emulation thread - */ - -void C64::Resume(void) -{ - if (thread_running && have_a_break) { - have_a_break = false; - release_sem(pause_sem); - TheSID->ResumeSound(); - } -} - - -/* - * Vertical blank: Poll keyboard and joysticks, update window - */ - -void C64::VBlank(bool draw_frame) -{ - bigtime_t elapsed_time; - long speed_index; - - // To avoid deadlocks on quitting - if (quit_thyself) return; - - // Pause requested? - if (have_a_break) { - release_sem(pause_sem); // Acknowledge pause - acquire_sem(pause_sem); // Wait for resume - } - - // Poll keyboard - TheDisplay->PollKeyboard(TheCIA1->KeyMatrix, TheCIA1->RevMatrix, &joykey); - - // Poll joysticks - TheCIA1->Joystick1 = poll_joystick(0); - TheCIA1->Joystick2 = poll_joystick(1); - - if (ThePrefs.JoystickSwap) { - uint8 tmp = TheCIA1->Joystick1; - TheCIA1->Joystick1 = TheCIA1->Joystick2; - TheCIA1->Joystick2 = tmp; - } - - // Joystick keyboard emulation - if (TheDisplay->NumLock()) - TheCIA1->Joystick1 &= joykey; - else - TheCIA1->Joystick2 &= joykey; - - // Count TOD clocks - TheCIA1->CountTOD(); - TheCIA2->CountTOD(); - - // Update window if needed - if (draw_frame) { - TheDisplay->Update(); - - // Calculate time between VBlanks, display speedometer - elapsed_time = system_time() - start_time; - speed_index = 20000 * 100 * ThePrefs.SkipFrames / (elapsed_time + 1); - - // Limit speed to 100% if desired (20ms/frame) - // If the SID emulation is on and no frames are skipped, synchronize to the SID - if (ThePrefs.LimitSpeed && speed_index > 100) { - if (ThePrefs.SIDType == SIDTYPE_DIGITAL && ThePrefs.SkipFrames == 1) { - long l; - get_sem_count(sound_sync_sem, &l); - if (l > 0) // Avoid C64 lagging behind - acquire_sem_etc(sound_sync_sem, l+1, 0, 0); - else - acquire_sem(sound_sync_sem); - } else - snooze(ThePrefs.SkipFrames * 20000 - elapsed_time); - speed_index = 100; - } - - start_time = system_time(); - - TheDisplay->Speedometer(speed_index); - } -} - - -/* - * Called by SID after playing 1/50 sec of sound - */ - -void C64::SoundSync(void) -{ - release_sem(sound_sync_sem); -} - - -/* - * Open/close joystick drivers given old and new state of - * joystick preferences - */ - -void C64::open_close_joystick(int port, int oldjoy, int newjoy) -{ - if (oldjoy != newjoy) { - joy_minx = joy_miny = 32767; // Reset calibration - joy_maxx = joy_maxy = 0; - if (joy[port]) { - if (joy_geek_port[port]) { - ((BDigitalPort *)joy[port])->Close(); - delete (BDigitalPort *)joy[port]; - } else { - ((BJoystick *)joy[port])->Close(); - delete (BJoystick *)joy[port]; - } - joy[port] = NULL; - } - switch (newjoy) { - case 1: - joy[port] = new BJoystick; - ((BJoystick *)joy[port])->Open("joystick1"); - joy_geek_port[port] = false; - break; - case 2: - joy[port] = new BJoystick; - ((BJoystick *)joy[port])->Open("joystick2"); - joy_geek_port[port] = false; - break; - case 3: - joy[port] = new BDigitalPort; - ((BDigitalPort *)joy[port])->Open("DigitalA"); - joy_geek_port[port] = true; - break; - case 4: - joy[port] = new BDigitalPort; - ((BDigitalPort *)joy[port])->Open("DigitalB"); - joy_geek_port[port] = true; - break; - } - } -} - -void C64::open_close_joysticks(int oldjoy1, int oldjoy2, int newjoy1, int newjoy2) -{ - open_close_joystick(0, oldjoy1, newjoy1); - open_close_joystick(1, oldjoy2, newjoy2); -} - - -/* - * Poll joystick port, return CIA mask - */ - -uint8 C64::poll_joystick(int port) -{ - uint8 j = 0xff; - - if (joy[port] == NULL) - return j; - - if (joy_geek_port[port]) { - - // GeekPort - uint8 val; - if (((BDigitalPort *)joy[port])->Read(&val) == 1) - j = val | 0xe0; - - } else { - - // Joystick port - BJoystick *p = (BJoystick *)joy[port]; - if (p->Update() != B_ERROR) { - if (p->horizontal > joy_maxx) - joy_maxx = p->horizontal; - if (p->horizontal < joy_minx) - joy_minx = p->horizontal; - if (p->vertical > joy_maxy) - joy_maxy = p->vertical; - if (p->vertical < joy_miny) - joy_miny = p->vertical; - - if (!p->button1) - j &= 0xef; // Button - - if (joy_maxx-joy_minx < 100 || joy_maxy-joy_miny < 100) - return j; - - if (p->horizontal < (joy_minx + (joy_maxx-joy_minx)/3)) - j &= 0xf7; // Right - else if (p->horizontal > (joy_minx + 2*(joy_maxx-joy_minx)/3)) - j &= 0xfb; // Left - - if (p->vertical < (joy_miny + (joy_maxy-joy_miny)/3)) - j &= 0xfd; // Down - else if (p->vertical > (joy_miny + 2*(joy_maxy-joy_miny)/3)) - j &= 0xfe; // Up - } - } - return j; -} - - -/* - * The emulation's main loop - */ - -long C64::thread_invoc(void *obj) -{ - ((C64 *)obj)->thread_func(); - return 0; -} - -void C64::thread_func(void) -{ -#ifdef PROFILING -static bigtime_t vic_time_acc = 0; -static bigtime_t sid_time_acc = 0; -static bigtime_t cia_time_acc = 0; -static bigtime_t cpu_time_acc = 0; -#endif -#ifdef FRODO_SC - while (!quit_thyself) { - // The order of calls is important here - if (TheVIC->EmulateCycle()) - TheSID->EmulateLine(); - TheCIA1->CheckIRQs(); - TheCIA2->CheckIRQs(); - TheCIA1->EmulateCycle(); - TheCIA2->EmulateCycle(); - TheCPU->EmulateCycle(); - - if (ThePrefs.Emul1541Proc) { - TheCPU1541->CountVIATimers(1); - if (!TheCPU1541->Idle) - TheCPU1541->EmulateCycle(); - } - CycleCounter++; -#else - while (!quit_thyself) { - // The order of calls is important here -#ifdef PROFILING -bigtime_t start_time = system_time(); -#endif - int cycles = TheVIC->EmulateLine(); -#ifdef PROFILING -bigtime_t vic_time = system_time(); -#endif - TheSID->EmulateLine(); -#ifdef PROFILING -bigtime_t sid_time = system_time(); -#endif -#if !PRECISE_CIA_CYCLES - TheCIA1->EmulateLine(ThePrefs.CIACycles); - TheCIA2->EmulateLine(ThePrefs.CIACycles); -#endif -#ifdef PROFILING -bigtime_t cia_time = system_time(); -#endif - - if (ThePrefs.Emul1541Proc) { - int cycles_1541 = ThePrefs.FloppyCycles; - TheCPU1541->CountVIATimers(cycles_1541); - - if (!TheCPU1541->Idle) { - // 1541 processor active, alternately execute - // 6502 and 6510 instructions until both have - // used up their cycles - while (cycles >= 0 || cycles_1541 >= 0) - if (cycles > cycles_1541) - cycles -= TheCPU->EmulateLine(1); - else - cycles_1541 -= TheCPU1541->EmulateLine(1); - } else - TheCPU->EmulateLine(cycles); - } else - // 1541 processor disabled, only emulate 6510 - TheCPU->EmulateLine(cycles); -#ifdef PROFILING -bigtime_t cpu_time = system_time(); -vic_time_acc += vic_time - start_time; -sid_time_acc += sid_time - vic_time; -cia_time_acc += cia_time - sid_time; -cpu_time_acc += cpu_time - cia_time; -#endif - -#endif - } - -#ifdef PROFILING -bigtime_t total_time = vic_time_acc + sid_time_acc + cia_time_acc + cpu_time_acc; -printf("VIC: %Ld\n", vic_time_acc * 100 / total_time); -printf("SID: %Ld\n", sid_time_acc * 100 / total_time); -printf("CIA: %Ld\n", cia_time_acc * 100 / total_time); -printf("CPU: %Ld\n", cpu_time_acc * 100 / total_time); -#endif -} diff --git a/Src/CmdPipe.cpp b/Src/CmdPipe.cpp deleted file mode 100644 index e740e92..0000000 --- a/Src/CmdPipe.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * CmdPipe.cpp - * - * Frodo (C) 1994-1997,2002-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "CmdPipe.h" - - -extern "C" { - #include - #include - #include - #include - #include - #include - #include - -#if defined(__alpha__) - #include -#endif - -#if defined(AIX) - #include -#else - #include -#endif - -#if defined(__linux__) - #include -#endif - - #include - #include -} - -static void kaputt(const char * c1, const char * c2) { - fprintf(stderr,"error: %s%s\n",c1,c2); - exit(20); -} - -Pipe::Pipe(void) : fail(true) { - - fds[0] = 0; - fds[1] = 1; - - if (-1 == pipe(fds)) { - kaputt("Pipe: ","unable to create pipe"); - return; - } - - fail = false; - return; -} - -Pipe::~Pipe(void) { - - if (! fail) { - close(fds[0]); - close(fds[1]); - } - return; -} - -unsigned long Pipe::ewrite(const void * buf, unsigned long len) { - - unsigned long wsum = 0; - while (len) { - long wlen; - - wlen = ::write(fds[1], buf, (long) len); - if (wlen <= 0) { - kaputt("Pipe::ewrite ","write-error"); - } - - len -= wlen; - buf = (void*) ((char*) buf + wlen); - wsum += wlen; - } - return wsum; -} - -unsigned long Pipe::eread(void * buf, unsigned long len) { - - unsigned long rsum = 0; - while (len) { - long rlen; - - rlen = ::read(fds[0], buf, (long) len); - - if (rlen <= 0) { - kaputt("Pipe::eread ","read-error"); - } - - len -= rlen; - buf = (void*) ((char*) buf + rlen); - rsum += rlen; - } - return rsum; -} - -int Pipe::probe(void) const { - - fd_set set; - FD_ZERO(&set); - FD_SET(fds[0], &set); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - - int res; -// Use the following commented line for HP-UX < 10.20 -// res = select(FD_SETSIZE, (int *)&set, (int *)0, (int *)0, &tv); - res = select(FD_SETSIZE, &set, (fd_set *)0, (fd_set *)0, &tv); - - if (res > 0) return -1; - return 0; - -} - -CmdPipe::CmdPipe(const char * command, const char * arg, int nicediff) : childpid(0), fail(true) { - - if (tocmd.fail || fromcmd.fail) { - kaputt("CmdPipe: ","unable to initialize pipes"); - return; - } - - childpid = fork(); - - if (childpid == -1) { - childpid = 0; - kaputt("CmdPipe: ","unable to fork process"); - return; - } - - if (childpid == 0) { - - if (nicediff) { - if (-1 == nice(nicediff)) { - fprintf(stderr,"CmdPipe: unable to change nice-level (non-fatal)"); - } - } - - dup2(tocmd.get_read_fd(), STDIN_FILENO); - - dup2(fromcmd.get_write_fd(), STDOUT_FILENO); - execlp(command, "Frodo_GUI", arg, (char *)0); - kaputt("CmdPipe: unable to execute child process ",command); - _exit(0); // exit (and do NOT call destructors etc..) - } - - fail = false; - return; -} - -CmdPipe::~CmdPipe(void) { - - if (childpid) { - int status; - waitpid(childpid, &status, 0); - - if (status != 0) { - fprintf(stderr,"~CmdPipe child process returned error\n"); - } - } -} diff --git a/Src/CmdPipe.h b/Src/CmdPipe.h deleted file mode 100644 index 4bff300..0000000 --- a/Src/CmdPipe.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * CmdPipe.h - * - * Frodo (C) 1994-1997,2002-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CmdPipe_h -#define CmdPipe_h - -extern "C" { - #include - #include -} - -class Pipe { - -protected: - - int fds[2]; - -public: - - bool fail; - - Pipe(void); - Pipe(int fdin, int fdout) : fail(false) { - fds[0] = fdin; - fds[1] = fdout; - } - ~Pipe(void); - - unsigned long ewrite(const void * buf, unsigned long len); - unsigned long eread (void * buf, unsigned long len); - - int get_read_fd(void) const { - return fds[0]; - } - - int get_write_fd(void) const { - return fds[1]; - } - - int probe(void) const; -}; - -class CmdPipe { - -protected: - - Pipe tocmd; - Pipe fromcmd; - - int childpid; - -public: - - bool fail; - - CmdPipe(const char * command, const char * arg, int nicediff = 0); - ~CmdPipe(void); - - unsigned long ewrite(const void * buf, unsigned long len) { - return tocmd.ewrite(buf, len); - } - - unsigned long eread (void * buf, unsigned long len) { - return fromcmd.eread(buf, len); - } - - int get_read_fd(void) const { - return fromcmd.get_read_fd(); - } - - int get_write_fd(void) const { - return tocmd.get_write_fd(); - } - - int probe(void) const { - return fromcmd.probe(); - } - -}; - -#endif // CmdPipe_h diff --git a/Src/SID_Amiga.h b/Src/SID_Amiga.h deleted file mode 100644 index ae92bb7..0000000 --- a/Src/SID_Amiga.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * SID_Amiga.h - 6581 emulation, Amiga specific stuff - * - * Frodo (C) 1994-1997,2002-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - - -// Library bases -struct Library *AHIBase; - -// CIA-A base -extern struct CIA ciaa; - - -/* - * Initialization, create sub-process - */ - -void DigitalRenderer::init_sound(void) -{ - // Find our (main) task - main_task = FindTask(NULL); - - // Create signal for communication - main_sig = AllocSignal(-1); - - // Create sub-process and wait until it is ready - if ((sound_process = CreateNewProcTags( - NP_Entry, (ULONG)&sub_invoc, - NP_Name, (ULONG)"Frodo Sound Process", - NP_Priority, 1, - NP_ExitData, (ULONG)this, // Easiest way to supply sub_invoc with this pointer - TAG_DONE)) != NULL) - Wait(1 << main_sig); -} - - -/* - * Destructor, delete sub-process - */ - -DigitalRenderer::~DigitalRenderer() -{ - // Tell sub-process to quit and wait for completion - if (sound_process != NULL) { - Signal(&(sound_process->pr_Task), 1 << quit_sig); - Wait(1 << main_sig); - } - - // Free signal - FreeSignal(main_sig); -} - - -/* - * Sample volume (for sampled voice) - */ - -void DigitalRenderer::EmulateLine(void) -{ - sample_buf[sample_in_ptr] = volume; - sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE; -} - - -/* - * Pause sound output - */ - -void DigitalRenderer::Pause(void) -{ - if (sound_process != NULL) - Signal(&(sound_process->pr_Task), 1 << pause_sig); -} - - -/* - * Resume sound output - */ - -void DigitalRenderer::Resume(void) -{ - if (sound_process != NULL) - Signal(&(sound_process->pr_Task), 1 << resume_sig); -} - - -/* - * Sound sub-process - */ - -void DigitalRenderer::sub_invoc(void) -{ - // Get pointer to the DigitalRenderer object and call sub_func() - DigitalRenderer *r = (DigitalRenderer *)((struct Process *)FindTask(NULL))->pr_ExitData; - r->sub_func(); -} - -void DigitalRenderer::sub_func(void) -{ - ahi_port = NULL; - ahi_io = NULL; - ahi_ctrl = NULL; - sample[0].ahisi_Address = sample[1].ahisi_Address = NULL; - ready = FALSE; - - // Create signals for communication - quit_sig = AllocSignal(-1); - pause_sig = AllocSignal(-1); - resume_sig = AllocSignal(-1); - ahi_sig = AllocSignal(-1); - - // Open AHI - if ((ahi_port = CreateMsgPort()) == NULL) - goto wait_for_quit; - if ((ahi_io = (struct AHIRequest *)CreateIORequest(ahi_port, sizeof(struct AHIRequest))) == NULL) - goto wait_for_quit; - ahi_io->ahir_Version = 2; - if (OpenDevice(AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, NULL)) - goto wait_for_quit; - AHIBase = (struct Library *)ahi_io->ahir_Std.io_Device; - - // Initialize callback hook - sf_hook.h_Entry = sound_func; - - // Open audio control structure - if ((ahi_ctrl = AHI_AllocAudio( - AHIA_AudioID, 0x0002000b, - AHIA_MixFreq, SAMPLE_FREQ, - AHIA_Channels, 1, - AHIA_Sounds, 2, - AHIA_SoundFunc, (ULONG)&sf_hook, - AHIA_UserData, (ULONG)this, - TAG_DONE)) == NULL) - goto wait_for_quit; - - // Prepare SampleInfos and load sounds (two sounds for double buffering) - sample[0].ahisi_Type = AHIST_M16S; - sample[0].ahisi_Length = SAMPLE_FREQ / CALC_FREQ; - sample[0].ahisi_Address = AllocVec(SAMPLE_FREQ / CALC_FREQ * 2, MEMF_PUBLIC | MEMF_CLEAR); - sample[1].ahisi_Type = AHIST_M16S; - sample[1].ahisi_Length = SAMPLE_FREQ / CALC_FREQ; - sample[1].ahisi_Address = AllocVec(SAMPLE_FREQ / CALC_FREQ * 2, MEMF_PUBLIC | MEMF_CLEAR); - if (sample[0].ahisi_Address == NULL || sample[1].ahisi_Address == NULL) - goto wait_for_quit; - AHI_LoadSound(0, AHIST_DYNAMICSAMPLE, &sample[0], ahi_ctrl); - AHI_LoadSound(1, AHIST_DYNAMICSAMPLE, &sample[1], ahi_ctrl); - - // Set parameters - play_buf = 0; - AHI_SetVol(0, 0x10000, 0x8000, ahi_ctrl, AHISF_IMM); - AHI_SetFreq(0, SAMPLE_FREQ, ahi_ctrl, AHISF_IMM); - AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, AHISF_IMM); - - // Start audio output - AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_DONE); - - // We are now ready for commands - ready = TRUE; - Signal(main_task, 1 << main_sig); - - // Accept and execute commands - for (;;) { - ULONG sigs = Wait((1 << quit_sig) | (1 << pause_sig) | (1 << resume_sig) | (1 << ahi_sig)); - - // Quit sub-process - if (sigs & (1 << quit_sig)) - goto quit; - - // Pause sound output - if (sigs & (1 << pause_sig)) - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_DONE); - - // Resume sound output - if (sigs & (1 << resume_sig)) - AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_DONE); - - // Calculate next buffer - if (sigs & (1 << ahi_sig)) - calc_buffer((int16 *)(sample[play_buf].ahisi_Address), sample[play_buf].ahisi_Length * 2); - } - -wait_for_quit: - // Initialization failed, wait for quit signal - Wait(1 << quit_sig); - -quit: - // Free everything - if (ahi_ctrl != NULL) { - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_DONE); - AHI_FreeAudio(ahi_ctrl); - CloseDevice((struct IORequest *)ahi_io); - } - - FreeVec(sample[0].ahisi_Address); - FreeVec(sample[1].ahisi_Address); - - if (ahi_io != NULL) - DeleteIORequest((struct IORequest *)ahi_io); - - if (ahi_port != NULL) - DeleteMsgPort(ahi_port); - - FreeSignal(quit_sig); - FreeSignal(pause_sig); - FreeSignal(resume_sig); - FreeSignal(ahi_sig); - - // Quit (synchronized with main task) - Forbid(); - Signal(main_task, 1 << main_sig); -} - - -/* - * AHI sound callback, play next buffer and signal sub-process - */ - -ULONG DigitalRenderer::sound_func(void) -{ - register struct AHIAudioCtrl *ahi_ctrl asm ("a2"); - DigitalRenderer *r = (DigitalRenderer *)ahi_ctrl->ahiac_UserData; - r->play_buf ^= 1; - AHI_SetSound(0, r->play_buf, 0, 0, ahi_ctrl, 0); - Signal(&(r->sound_process->pr_Task), 1 << (r->ahi_sig)); - return 0; -} - - -/* - * Renderer for SID card - */ - -// Renderer class -class SIDCardRenderer : public SIDRenderer { -public: - SIDCardRenderer(); - virtual ~SIDCardRenderer(); - - virtual void Reset(void); - virtual void EmulateLine(void) {} - virtual void WriteRegister(uint16 adr, uint8 byte); - virtual void NewPrefs(Prefs *prefs) {} - virtual void Pause(void) {} - virtual void Resume(void) {} - -private: - UBYTE *sid_base; // SID card base pointer -}; - -// Constructor: Reset SID -SIDCardRenderer::SIDCardRenderer() -{ - sid_base = (UBYTE *)0xa00001; - Reset(); -} - -// Destructor: Reset SID -SIDCardRenderer::~SIDCardRenderer() -{ - Reset(); -} - -// Reset SID -void SIDCardRenderer::Reset(void) -{ - WaitTOF(); - ciaa.ciapra |= CIAF_LED; - WaitTOF(); - ciaa.ciapra &= ~CIAF_LED; -} - -// Write to register -void SIDCardRenderer::WriteRegister(uint16 adr, uint8 byte) -{ - sid_base[adr << 1] = byte; -}