#floppyImage1 = ./disks/temp.nib
#floppyImage1 = ./disks/temp.dsk
# Yes
-floppyImage1 = ./disks/bt1_boot.dsk
+#floppyImage1 = ./disks/bt1_boot.dsk
# Yes
-#floppyImage1 = ./disks/bt2_boot.dsk
+floppyImage1 = ./disks/bt2_boot.dsk
# No (gets stuck on 1st track)
#floppyImage1 = ./disks/bt3_boot.dsk
# Yes
}
else if ((addr & 0xFFF0) == 0xC030)
{
+/*
+This is problematic, mainly because the v65C02 removes actual cycles run after each call.
+Therefore, we don't really have a reliable method of sending a timestamp to the sound routine.
+How to fix?
+
+What we need to send is a delta T value but related to the IRQ buffer routine. E.g., if the buffer
+hasn't had any changes in it then we just fill it with the last sample value and are done. Then
+we need to adjust our delta T accordingly. What we could do is keep a running total of time since the
+last change and adjust it accordingly, i.e., whenever a sound IRQ happens.
+How to keep track?
+
+Have deltaT somewhere. Then, whenever there's a toggle, backfill buffer with last spkr state and reset
+deltaT to zero. In the sound IRQ, if deltaT > buffer size, then subtract buffer size from deltaT. (?)
+
+
+
+*/
ToggleSpeaker(GetCurrentV65C02Clock());
//should it return something else here???
return 0x00;
SetCallbackTime(FrameCallback, 16666.66666667);
//Instead of this, we should yield remaining time to other processes... !!! FIX !!!
+//lessee...
+//nope. SDL_Delay(10);
while (SDL_GetTicks() - startTicks < 16); // Wait for next frame...
startTicks = SDL_GetTicks();
}
#include "log.h"
+#define SAMPLE_RATE (44100.0)
+#define SAMPLES_PER_FRAME (SAMPLE_RATE / 60.0)
+#define CYCLES_PER_SAMPLE ((1024000.0 / 60.0) / (SAMPLES_PER_FRAME))
+#define SOUND_BUFFER_SIZE 8192
#define AMPLITUDE (32) // -32 - +32 seems to be plenty loud!
// Global variables
static SDL_AudioSpec desired;
static bool soundInitialized = false;
static bool speakerState;
-static uint8 soundBuffer[4096];
+static uint8 soundBuffer[SOUND_BUFFER_SIZE];
static uint32 soundBufferPos;
static uint32 sampleBase;
static SDL_cond * conditional = NULL;
return;
#endif
- desired.freq = 44100; // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
+ desired.freq = SAMPLE_RATE; // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
desired.format = AUDIO_S8; // This uses the native endian (for portability)...
// desired.format = AUDIO_S16SYS; // This uses the native endian (for portability)...
desired.channels = 1;
// (or do we?)
SDL_LockAudio();
- uint32 currentPos = sampleBase + (uint32)((double)time / 23.2199);
+ uint32 currentPos = sampleBase + (uint32)((double)time / CYCLES_PER_SAMPLE);
- if (currentPos > 4095)
+ if (currentPos > SOUND_BUFFER_SIZE - 1)
{
#if 0
WriteLog("ToggleSpeaker() about to go into spinlock at time: %08X (%u) (sampleBase=%u)!\n", time, time, sampleBase);
return;
SDL_LockAudio();
- sampleBase += 735;
+ sampleBase += SAMPLES_PER_FRAME;
SDL_UnlockAudio();
}
+
+/*
+A better way might be as follows:
+
+Keep timestamp array of speaker toggle times. In the sound routine, unpack as many as will fit
+into the given buffer and keep going. Have the toggle function check to see if the buffer is full,
+and if it is, way for a signal from the interrupt that there's room for more. Can keep a circular
+buffer. Also, would need a timestamp buffer on the order of 2096 samples *in theory* could toggle
+each sample
+
+Instead of a timestamp, just keep a delta. That way, don't need to deal with wrapping and all that
+(though the timestamp could wrap--need to check into that)
+
+Need to consider corner cases where a sound IRQ happens but no speaker toggle happened.
+
+*/
+
+
+