aboutsummaryrefslogtreecommitdiff
path: root/c64/sid.c
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2012-02-10 14:25:38 +0100
committerReiner Herrmann <reiner@reiner-h.de>2012-02-10 14:25:38 +0100
commita5d7e68af96d9b62821d8fd47f5039c5bae5d421 (patch)
treeab7d1a70312afb74dc7184d8b269b08f332f4b74 /c64/sid.c
added original sam_player code
Diffstat (limited to 'c64/sid.c')
-rw-r--r--c64/sid.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/c64/sid.c b/c64/sid.c
new file mode 100644
index 0000000..845f799
--- /dev/null
+++ b/c64/sid.c
@@ -0,0 +1,91 @@
+// sid.c
+//
+// 20060803 Markku Alén
+
+#include "sid.h"
+#include "c64.h"
+
+static int record_init;
+static unsigned int record_freq;
+static unsigned char *record_buffer;
+static unsigned int record_max_len;
+static unsigned int record_index;
+
+void start_record(unsigned int frequency, unsigned char *wave_buf, unsigned int wave_max_len)
+{
+ record_init = 1;
+ record_freq = frequency;
+ record_buffer = wave_buf;
+ record_max_len = wave_max_len;
+ record_index = 0;
+}
+
+unsigned int stop_record(void)
+{
+ unsigned int len;
+ len = record_index;
+ record_freq = 0;
+ record_buffer = 0;
+ record_max_len = 0;
+ record_index = 0;
+ return len;
+}
+
+static void record(unsigned int counter, unsigned int sample)
+{
+ static unsigned int last_counter;
+ static unsigned int last_sample;
+ unsigned int elapsed;
+ if(record_init)
+ {
+ record_init = 0;
+ last_counter = counter;
+ }
+ elapsed = ((record_freq * (counter - last_counter)) + (F_CPU / 2)) / F_CPU;
+ while(elapsed-- > 0)
+ {
+ if(record_index < record_max_len)
+ record_buffer[record_index] = sample;
+ record_index += 1;
+ }
+ last_counter = counter;
+}
+
+static int volume;
+
+static unsigned char regs[32];
+
+void sid_init(void)
+{
+ int i;
+ for(i = sizeof(regs);i-- > 0;)
+ regs[i] = 0x00;
+ (void)stop_record();
+ volume = 0;
+}
+
+int sid_read(int address)
+{
+ switch(address & 0x001f)
+ {
+ case 0x0018:
+ return volume;
+ default:
+ return regs[address % sizeof(regs)];
+ }
+}
+
+void sid_write(int address, int data)
+{
+ switch(address & 0x001f)
+ {
+ case 0x0018:
+ volume = data & 0x0f;
+ if(record_buffer != 0)
+ record(total_cycles, (volume << 4) | volume);
+ break;
+ default:
+ regs[address % sizeof(regs)] = data;
+ }
+}
+