Mercurial > repos > blastem
annotate psg.c @ 2521:8cf7cadc17ee
Initial SC-3000 support
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 11 Oct 2024 00:46:53 -0700 |
parents | f6213de4224c |
children | 7e1215d17571 |
rev | line source |
---|---|
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
410
diff
changeset
|
1 /* |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
410
diff
changeset
|
2 Copyright 2013 Michael Pavone |
483
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
3 This file is part of BlastEm. |
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
410
diff
changeset
|
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
410
diff
changeset
|
5 */ |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 #include "psg.h" |
505
b7b7a1cab44a
The local clone on my laptop got messed up and some changes had not been pushed. This commit represents the status of the working copy from that clone. It unfortunately contains some changes that I did not intend to commit yet, but this seems like the best option at the moment.
Michael Pavone <pavone@retrodev.com>
parents:
483
diff
changeset
|
7 #include "blastem.h" |
1946 | 8 #include "event_log.h" |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 #include <string.h> |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 #include <stdlib.h> |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
11 #include <stdio.h> |
964
e6dc30231b83
Fix PSG linear resampling and implement a low pass filter
Michael Pavone <pavone@retrodev.com>
parents:
963
diff
changeset
|
12 #include <math.h> |
1555
6ce36c3f250b
More audio refactoring in preparation for allowing proper sync to video with dynamic audio rate control
Michael Pavone <pavone@retrodev.com>
parents:
1551
diff
changeset
|
13 void psg_init(psg_context * context, uint32_t master_clock, uint32_t clock_div) |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 memset(context, 0, sizeof(*context)); |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
16 context->audio = render_audio_source("PSG", master_clock, clock_div, 2); |
380
1c8d74f2ab0b
Make the PSG and YM2612 use the master clock internal with an increment based on clock divider so that they stay perflectly in sync. Run both the PSG and YM2612 whenver one of them needs to be run.
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
17 context->clock_inc = clock_div; |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 for (int i = 0; i < 4; i++) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 context->volume[i] = 0xF; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 } |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
21 context->pan = 0xFF; |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 |
2255
74112041b2c7
Proper calculation of sample rate for YM2612/PSG oscilloscope view
Michael Pavone <pavone@retrodev.com>
parents:
2246
diff
changeset
|
24 void psg_enable_scope(psg_context *context, oscilloscope *scope, uint32_t master_clock) |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
25 { |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
26 #ifndef IS_LIB |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
27 context->scope = scope; |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
28 static const char *names[] = { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
29 "PSG #1", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
30 "PSG #2", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
31 "PSG #3", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
32 "PSG Noise", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
33 }; |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
34 for (int i = 0; i < 4; i++) |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
35 { |
2255
74112041b2c7
Proper calculation of sample rate for YM2612/PSG oscilloscope view
Michael Pavone <pavone@retrodev.com>
parents:
2246
diff
changeset
|
36 context->scope_channel[i] = scope_add_channel(scope, names[i], master_clock / context->clock_inc); |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
37 } |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
38 #endif |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
39 } |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
40 |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
41 void psg_free(psg_context *context) |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
42 { |
1551
ce1f93be0104
Small cleanup to audio interface between emulation code and renderer backend
Michael Pavone <pavone@retrodev.com>
parents:
1451
diff
changeset
|
43 render_free_source(context->audio); |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
44 free(context); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
45 } |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
46 |
483
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
47 void psg_adjust_master_clock(psg_context * context, uint32_t master_clock) |
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
48 { |
1555
6ce36c3f250b
More audio refactoring in preparation for allowing proper sync to video with dynamic audio rate control
Michael Pavone <pavone@retrodev.com>
parents:
1551
diff
changeset
|
49 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc); |
483
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
50 } |
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
51 |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 void psg_write(psg_context * context, uint8_t value) |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 { |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
54 if (context->vgm) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
55 vgm_sn76489_write(context->vgm, context->cycles, value); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
56 } |
1946 | 57 event_log(EVENT_PSG_REG, context->cycles, sizeof(value), &value); |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 if (value & 0x80) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 context->latch = value & 0x70; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 uint8_t channel = value >> 5 & 0x3; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 if (value & 0x10) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 context->volume[channel] = value & 0xF; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 if (channel == 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 switch(value & 0x3) |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 case 0: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 case 1: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 case 2: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 context->counter_load[3] = 0x10 << (value & 0x3); |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 context->noise_use_tone = 0; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 break; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 default: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 context->counter_load[3] = context->counter_load[2]; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 context->noise_use_tone = 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 context->noise_type = value & 0x4; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 context->lsfr = 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 context->counter_load[channel] = (context->counter_load[channel] & 0x3F0) | (value & 0xF); |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 if (channel == 2 && context->noise_use_tone) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 context->counter_load[3] = context->counter_load[2]; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 if (!(context->latch & 0x10)) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 uint8_t channel = context->latch >> 5 & 0x3; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 if (channel != 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 context->counter_load[channel] = (value << 4 & 0x3F0) | (context->counter_load[channel] & 0xF); |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 if (channel == 2 && context->noise_use_tone) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 context->counter_load[3] = context->counter_load[2]; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 |
522
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
99 #define PSG_VOL_DIV 14 |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 //table shamelessly swiped from PSG doc from smspower.org |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
102 static int16_t volume_table[16] = { |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 32767/PSG_VOL_DIV, 26028/PSG_VOL_DIV, 20675/PSG_VOL_DIV, 16422/PSG_VOL_DIV, 13045/PSG_VOL_DIV, 10362/PSG_VOL_DIV, |
483
3e1573fa22cf
Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
104 8231/PSG_VOL_DIV, 6568/PSG_VOL_DIV, 5193/PSG_VOL_DIV, 4125/PSG_VOL_DIV, 3277/PSG_VOL_DIV, 2603/PSG_VOL_DIV, |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 2067/PSG_VOL_DIV, 1642/PSG_VOL_DIV, 1304/PSG_VOL_DIV, 0 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 }; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 void psg_run(psg_context * context, uint32_t cycles) |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 while (context->cycles < cycles) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
111 uint8_t trigger[4] = {0,0,0,0}; |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 for (int i = 0; i < 4; i++) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 if (context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 context->counters[i] -= 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 if (!context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 context->counters[i] = context->counter_load[i]; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 context->output_state[i] = !context->output_state[i]; |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
119 trigger[i] = context->output_state[i]; |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 if (i == 3 && context->output_state[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 context->noise_out = context->lsfr & 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 context->lsfr = (context->lsfr >> 1) | (context->lsfr << 15); |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 if (context->noise_type) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 //white noise |
2212
71b0cb7c34a6
Fix PSG white noise LSFR tap
Michael Pavone <pavone@retrodev.com>
parents:
2196
diff
changeset
|
125 if (context->lsfr & 0x4) { |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 context->lsfr ^= 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 } |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
132 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
133 int16_t left_accum = 0, right_accum = 0; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
134 uint8_t pan_left = 0x10, pan_right = 0x1; |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
135 |
2246
0e927fce8941
Fix bug in PSG oscilloscope output
Michael Pavone <pavone@retrodev.com>
parents:
2243
diff
changeset
|
136 int16_t value; |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
137 for (int i = 0; i < 3; i++) { |
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
138 if (context->output_state[i]) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
139 value = volume_table[context->volume[i]]; |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
140 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
141 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
142 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
143 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
144 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
145 } |
2246
0e927fce8941
Fix bug in PSG oscilloscope output
Michael Pavone <pavone@retrodev.com>
parents:
2243
diff
changeset
|
146 } else { |
0e927fce8941
Fix bug in PSG oscilloscope output
Michael Pavone <pavone@retrodev.com>
parents:
2243
diff
changeset
|
147 value = 0; |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
148 } |
2373
f6213de4224c
Fix psg panning implementation
Michael Pavone <pavone@retrodev.com>
parents:
2302
diff
changeset
|
149 pan_left <<= 1; |
f6213de4224c
Fix psg panning implementation
Michael Pavone <pavone@retrodev.com>
parents:
2302
diff
changeset
|
150 pan_right <<= 1; |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
151 #ifndef IS_LIB |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
152 if (context->scope) { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
153 scope_add_sample(context->scope, context->scope_channel[i], value, trigger[i]); |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
154 } |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
155 #endif |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
156 } |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
157 value = 0; |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
158 if (context->noise_out) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
159 value = volume_table[context->volume[3]]; |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
160 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
161 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
162 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
163 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
164 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
165 } |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
166 } |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
167 #ifndef IS_LIB |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
168 if (context->scope) { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
169 scope_add_sample(context->scope, context->scope_channel[3], value, trigger[3]); |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
170 } |
2302
0343f0d5add0
Fix libretro build for real
Michael Pavone <pavone@retrodev.com>
parents:
2255
diff
changeset
|
171 #endif |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
172 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
173 render_put_stereo_sample(context->audio, left_accum, right_accum); |
838
9a5dc22297f2
Somewhat better handling of high frequency PSG tones. Needs work to fully handle case where frequency > half our output sample rate
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
174 |
380
1c8d74f2ab0b
Make the PSG and YM2612 use the master clock internal with an increment based on clock divider so that they stay perflectly in sync. Run both the PSG and YM2612 whenver one of them needs to be run.
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
175 context->cycles += context->clock_inc; |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
179 void psg_vgm_log(psg_context *context, uint32_t master_clock, vgm_writer *vgm) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
180 { |
1911
f2ed8df7a002
Fix PSG frequency written to VGM header when logging
Michael Pavone <pavone@retrodev.com>
parents:
1909
diff
changeset
|
181 vgm_sn76489_init(vgm, 16 * master_clock / context->clock_inc, 9, 16, 0); |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
182 context->vgm = vgm; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
183 for (int chan = 0; chan < 4; chan++) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
184 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
185 uint8_t base = chan << 5 | 0x80; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
186 vgm_sn76489_write(context->vgm, context->cycles, context->volume[chan] | base | 0x10); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
187 if (chan == 3) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
188 if (context->noise_use_tone) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
189 vgm_sn76489_write(context->vgm, context->cycles, 3 | base); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
190 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
191 //0x10 = 0 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
192 //0x20 = 1 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
193 //0x40 = 2 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
194 vgm_sn76489_write(context->vgm, context->cycles, context->counter_load[chan] >> 5 | base); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
195 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
196 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
197 vgm_sn76489_write(context->vgm, context->cycles, (context->counter_load[chan] & 0xF) | base); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
198 vgm_sn76489_write(context->vgm, context->cycles, context->counter_load[chan] >> 4 & 0x3F); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
199 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
200 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
201 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
202 |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
203 void psg_serialize(psg_context *context, serialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
204 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
205 save_int16(buf, context->lsfr); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
206 save_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
207 save_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
208 save_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
209 uint8_t output_state = context->output_state[0] << 3 | context->output_state[1] << 2 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
210 | context->output_state[2] << 1 | context->output_state[3] |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
211 | context->noise_use_tone << 4; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
212 save_int8(buf, output_state); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
213 save_int8(buf, context->noise_type); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
214 save_int8(buf, context->latch); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
215 save_int32(buf, context->cycles); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
216 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
217 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
218 void psg_deserialize(deserialize_buffer *buf, void *vcontext) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
219 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
220 psg_context *context = vcontext; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
221 context->lsfr = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
222 load_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
223 load_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
224 load_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
225 uint8_t output_state = load_int8(buf); |
1451
9c65819afec3
Fix operator precedence in psg serialize/deserialize
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
226 context->output_state[0] = output_state >> 3 & 1; |
9c65819afec3
Fix operator precedence in psg serialize/deserialize
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
227 context->output_state[1] = output_state >> 2 & 1; |
9c65819afec3
Fix operator precedence in psg serialize/deserialize
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
228 context->output_state[2] = output_state >> 1 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
229 context->output_state[3] = output_state & 1; |
1451
9c65819afec3
Fix operator precedence in psg serialize/deserialize
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
230 context->noise_use_tone = output_state >> 4 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
231 context->noise_type = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
232 context->latch = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
233 context->cycles = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
234 } |