Mercurial > repos > blastem
annotate psg.c @ 2237:f82c090c1e89
Implement MMAP_ONLY_ODD/EVEN in combination with MMAP_PTR_IDX. Fixes games that have SRAM when a system with TMSS is selected
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 17 Sep 2022 15:38:40 -0700 |
parents | 71b0cb7c34a6 |
children | 0d1d5dccdd28 |
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 |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
24 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
|
25 { |
1551
ce1f93be0104
Small cleanup to audio interface between emulation code and renderer backend
Michael Pavone <pavone@retrodev.com>
parents:
1451
diff
changeset
|
26 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
|
27 free(context); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
28 } |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
843
diff
changeset
|
29 |
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
|
30 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
|
31 { |
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
|
32 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
|
33 } |
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
|
34 |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 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
|
36 { |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
37 if (context->vgm) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
38 vgm_sn76489_write(context->vgm, context->cycles, value); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
39 } |
1946 | 40 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
|
41 if (value & 0x80) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 context->latch = value & 0x70; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 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
|
44 if (value & 0x10) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 context->volume[channel] = value & 0xF; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 if (channel == 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 switch(value & 0x3) |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 case 0: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 case 1: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 case 2: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 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
|
54 context->noise_use_tone = 0; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 break; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 default: |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 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
|
58 context->noise_use_tone = 1; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 context->noise_type = value & 0x4; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 context->lsfr = 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 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
|
64 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
|
65 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
|
66 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 } else { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 if (!(context->latch & 0x10)) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 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
|
72 if (channel != 3) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 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
|
74 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
|
75 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
|
76 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 |
522
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
82 #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
|
83 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 //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
|
85 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
|
86 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
|
87 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
|
88 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
|
89 }; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 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
|
92 { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 while (context->cycles < cycles) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 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
|
95 if (context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 context->counters[i] -= 1; |
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 if (!context->counters[i]) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 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
|
100 context->output_state[i] = !context->output_state[i]; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 if (context->noise_type) { |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 //white noise |
2212
71b0cb7c34a6
Fix PSG white noise LSFR tap
Michael Pavone <pavone@retrodev.com>
parents:
2196
diff
changeset
|
106 if (context->lsfr & 0x4) { |
354
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 context->lsfr ^= 0x8000; |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 } |
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 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 } |
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
|
113 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
114 int16_t left_accum = 0, right_accum = 0; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
115 uint8_t pan_left = 0x10, pan_right = 0x1; |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
116 |
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
|
117 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
|
118 if (context->output_state[i]) { |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
119 int16_t value = volume_table[context->volume[i]]; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
120 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
121 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
122 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
123 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
124 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
125 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
126 pan_left <<= 1; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
127 pan_right <<= 1; |
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
|
128 } |
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
|
129 } |
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 if (context->noise_out) { |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
131 int16_t value = volume_table[context->volume[3]]; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
132 if (context->pan & pan_left) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
133 left_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
134 } |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
135 if (context->pan & pan_right) { |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
136 right_accum += value; |
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
137 } |
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
|
138 } |
2081
cfd53c94fffb
Initial stab at RF5C164 emulation
Michael Pavone <pavone@retrodev.com>
parents:
1946
diff
changeset
|
139 |
2196
2648081f3100
Implement Game Gear PSG panning
Michael Pavone <pavone@retrodev.com>
parents:
2081
diff
changeset
|
140 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
|
141 |
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
|
142 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
|
143 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 } |
15dd6418fe67
Initial PSG support. Mostly works, noise channel is borked though.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 |
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
146 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
|
147 { |
1911
f2ed8df7a002
Fix PSG frequency written to VGM header when logging
Michael Pavone <pavone@retrodev.com>
parents:
1909
diff
changeset
|
148 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
|
149 context->vgm = vgm; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
150 for (int chan = 0; chan < 4; chan++) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
151 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
152 uint8_t base = chan << 5 | 0x80; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
153 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
|
154 if (chan == 3) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
155 if (context->noise_use_tone) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
156 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
|
157 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
158 //0x10 = 0 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
159 //0x20 = 1 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
160 //0x40 = 2 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
161 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
|
162 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
163 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
164 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
|
165 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
|
166 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
167 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
168 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
1865
diff
changeset
|
169 |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
170 void psg_serialize(psg_context *context, serialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
171 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
172 save_int16(buf, context->lsfr); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
173 save_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
174 save_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
175 save_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
176 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
|
177 | context->output_state[2] << 1 | context->output_state[3] |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
178 | context->noise_use_tone << 4; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
179 save_int8(buf, output_state); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
180 save_int8(buf, context->noise_type); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
181 save_int8(buf, context->latch); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
182 save_int32(buf, context->cycles); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
183 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
184 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
185 void psg_deserialize(deserialize_buffer *buf, void *vcontext) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
186 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
187 psg_context *context = vcontext; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
188 context->lsfr = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
189 load_buffer16(buf, context->counter_load, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
190 load_buffer16(buf, context->counters, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
191 load_buffer8(buf, context->volume, 4); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
192 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
|
193 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
|
194 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
|
195 context->output_state[2] = output_state >> 1 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
196 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
|
197 context->noise_use_tone = output_state >> 4 & 1; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
198 context->noise_type = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
199 context->latch = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
200 context->cycles = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
201 } |