Mercurial > repos > blastem
annotate psg.c @ 2274:bf1bb893f104
Properly ignore low bits of SP start address in disassembler
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 29 Dec 2022 22:44:35 -0800 |
parents | 74112041b2c7 |
children | 0343f0d5add0 |
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 { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
26 context->scope = scope; |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
27 static const char *names[] = { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
28 "PSG #1", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
29 "PSG #2", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
30 "PSG #3", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
31 "PSG Noise", |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
32 }; |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
33 for (int i = 0; i < 4; i++) |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
34 { |
2255
74112041b2c7
Proper calculation of sample rate for YM2612/PSG oscilloscope view
Michael Pavone <pavone@retrodev.com>
parents:
2246
diff
changeset
|
35 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
|
36 } |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
37 } |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
38 |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
39 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
|
40 { |
1551
ce1f93be0104
Small cleanup to audio interface between emulation code and renderer backend
Michael Pavone <pavone@retrodev.com>
parents:
1451
diff
changeset
|
41 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
|
42 free(context); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
43 } |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
44 |
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
|
45 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
|
46 { |
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
|
47 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
|
48 } |
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
|
49 |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 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
|
51 { |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
52 if (context->vgm) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
53 vgm_sn76489_write(context->vgm, context->cycles, value); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
54 } |
1946 | 55 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
|
56 if (value & 0x80) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 context->latch = value & 0x70; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 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
|
59 if (value & 0x10) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 context->volume[channel] = value & 0xF; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 if (channel == 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 switch(value & 0x3) |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 case 0: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 case 1: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 case 2: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 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
|
69 context->noise_use_tone = 0; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 break; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 default: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 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
|
73 context->noise_use_tone = 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 context->noise_type = value & 0x4; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 context->lsfr = 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 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
|
79 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
|
80 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
|
81 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 } |
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 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 if (!(context->latch & 0x10)) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 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
|
87 if (channel != 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 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
|
89 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
|
90 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
|
91 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 } |
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 |
522
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
97 #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
|
98 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 //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
|
100 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
|
101 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
|
102 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
|
103 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
|
104 }; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 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
|
107 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 while (context->cycles < cycles) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
109 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
|
110 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
|
111 if (context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 context->counters[i] -= 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 if (!context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 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
|
116 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
|
117 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
|
118 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
|
119 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
|
120 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
|
121 if (context->noise_type) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 //white noise |
2212
71b0cb7c34a6
Fix PSG white noise LSFR tap
Michael Pavone <pavone@retrodev.com>
parents:
2196
diff
changeset
|
123 if (context->lsfr & 0x4) { |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 context->lsfr ^= 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 } |
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 } |
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
|
130 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
131 int16_t left_accum = 0, right_accum = 0; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
132 uint8_t pan_left = 0x10, pan_right = 0x1; |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
133 |
2246
0e927fce8941
Fix bug in PSG oscilloscope output
Michael Pavone <pavone@retrodev.com>
parents:
2243
diff
changeset
|
134 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
|
135 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
|
136 if (context->output_state[i]) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
137 value = volume_table[context->volume[i]]; |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
138 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
139 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
140 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
141 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
142 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
143 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
144 pan_left <<= 1; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
145 pan_right <<= 1; |
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 } |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
149 if (context->scope) { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
150 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
|
151 } |
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
|
152 } |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
153 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
|
154 if (context->noise_out) { |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
155 value = volume_table[context->volume[3]]; |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
156 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
157 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
158 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
159 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
160 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
161 } |
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
|
162 } |
2243
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
163 if (context->scope) { |
0d1d5dccdd28
Initial implementation of oscilloscope debug view
Michael Pavone <pavone@retrodev.com>
parents:
2212
diff
changeset
|
164 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
|
165 } |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
166 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
167 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
|
168 |
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
|
169 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
|
170 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
173 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
|
174 { |
1911
f2ed8df7a002
Fix PSG frequency written to VGM header when logging
Michael Pavone <pavone@retrodev.com>
parents:
1909
diff
changeset
|
175 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
|
176 context->vgm = vgm; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
177 for (int chan = 0; chan < 4; chan++) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
178 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
179 uint8_t base = chan << 5 | 0x80; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
180 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
|
181 if (chan == 3) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
182 if (context->noise_use_tone) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
183 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
|
184 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
185 //0x10 = 0 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
186 //0x20 = 1 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
187 //0x40 = 2 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
188 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
|
189 } |
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 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
|
192 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
|
193 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
194 } |
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 |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
197 void psg_serialize(psg_context *context, serialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
198 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
199 save_int16(buf, context->lsfr); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
200 save_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
201 save_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
202 save_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
203 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
|
204 | context->output_state[2] << 1 | context->output_state[3] |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
205 | context->noise_use_tone << 4; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
206 save_int8(buf, output_state); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
207 save_int8(buf, context->noise_type); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
208 save_int8(buf, context->latch); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
209 save_int32(buf, context->cycles); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
210 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
211 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
212 void psg_deserialize(deserialize_buffer *buf, void *vcontext) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
213 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
214 psg_context *context = vcontext; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
215 context->lsfr = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
216 load_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
217 load_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
218 load_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
219 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
|
220 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
|
221 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
|
222 context->output_state[2] = output_state >> 1 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
223 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
|
224 context->noise_use_tone = output_state >> 4 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
225 context->noise_type = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
226 context->latch = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
227 context->cycles = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
228 } |