Mercurial > repos > blastem
annotate ym2612.c @ 1569:0ec89dadb36d
Add code for loading PNG images. Added 360 controller image. WIP work on gamepad mapping UI
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 19 Apr 2018 00:51:10 -0700 |
parents | 6ce36c3f250b |
children | 4637ab86be8c |
rev | line source |
---|---|
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
451
diff
changeset
|
1 /* |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
451
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:
451
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:
451
diff
changeset
|
5 */ |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 #include <string.h> |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
7 #include <math.h> |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
8 #include <stdio.h> |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
9 #include <stdlib.h> |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 #include "ym2612.h" |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
11 #include "render.h" |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
12 #include "wave.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
|
13 #include "blastem.h" |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
15 //#define DO_DEBUG_PRINT |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
16 #ifdef DO_DEBUG_PRINT |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
17 #define dfprintf fprintf |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
18 #define dfopen(var, fname, mode) var=fopen(fname, mode) |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
19 #else |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
20 #define dfprintf |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
21 #define dfopen(var, fname, mode) |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
22 #endif |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
23 |
535
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
24 #define BUSY_CYCLES_ADDRESS 17 |
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
25 #define BUSY_CYCLES_DATA_LOW 83 |
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
26 #define BUSY_CYCLES_DATA_HIGH 47 |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
27 #define OP_UPDATE_PERIOD 144 |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 #define BIT_TIMERA_ENABLE 0x1 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 #define BIT_TIMERB_ENABLE 0x2 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 #define BIT_TIMERA_OVEREN 0x4 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 #define BIT_TIMERB_OVEREN 0x8 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 #define BIT_TIMERA_RESET 0x10 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 #define BIT_TIMERB_RESET 0x20 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
36 #define BIT_TIMERA_LOAD 0x40 |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
37 #define BIT_TIMERB_LOAD 0x80 |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
38 |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 #define BIT_STATUS_TIMERA 0x1 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 #define BIT_STATUS_TIMERB 0x2 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
42 static uint32_t ym_calc_phase_inc(ym2612_context * context, ym_operator * operator, uint32_t op); |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
43 |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
44 enum { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
45 PHASE_ATTACK, |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
46 PHASE_DECAY, |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
47 PHASE_SUSTAIN, |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
48 PHASE_RELEASE |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
49 }; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
50 |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
51 uint8_t did_tbl_init = 0; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
52 //According to Nemesis, real hardware only uses a 256 entry quarter sine table; however, |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
53 //memory is cheap so using a half sine table will probably save some cycles |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
54 //a full sine table would be nice, but negative numbers don't get along with log2 |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
55 #define SINE_TABLE_SIZE 512 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
56 static uint16_t sine_table[SINE_TABLE_SIZE]; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
57 //Similar deal here with the power table for log -> linear conversion |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
58 //According to Nemesis, real hardware only uses a 256 entry table for the fractional part |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
59 //and uses the whole part as a shift amount. |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
60 #define POW_TABLE_SIZE (1 << 13) |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
61 static uint16_t pow_table[POW_TABLE_SIZE]; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
62 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
63 static uint16_t rate_table_base[] = { |
362 | 64 //main portion |
65 0,1,0,1,0,1,0,1, | |
66 0,1,0,1,1,1,0,1, | |
67 0,1,1,1,0,1,1,1, | |
68 0,1,1,1,1,1,1,1, | |
69 //top end | |
70 1,1,1,1,1,1,1,1, | |
71 1,1,1,2,1,1,1,2, | |
72 1,2,1,2,1,2,1,2, | |
73 1,2,2,2,1,2,2,2, | |
74 }; | |
75 | |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
76 static uint16_t rate_table[64*8]; |
362 | 77 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
78 static uint8_t lfo_timer_values[] = {108, 77, 71, 67, 62, 44, 8, 5}; |
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
79 static uint8_t lfo_pm_base[][8] = { |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
80 {0, 0, 0, 0, 0, 0, 0, 0}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
81 {0, 0, 0, 0, 4, 4, 4, 4}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
82 {0, 0, 0, 4, 4, 4, 8, 8}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
83 {0, 0, 4, 4, 8, 8, 0xc, 0xc}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
84 {0, 0, 4, 8, 8, 8, 0xc,0x10}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
85 {0, 0, 8, 0xc,0x10,0x10,0x14,0x18}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
86 {0, 0,0x10,0x18,0x20,0x20,0x28,0x30}, |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
87 {0, 0,0x20,0x30,0x40,0x40,0x50,0x60} |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
88 }; |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
89 static int16_t lfo_pm_table[128 * 32 * 8]; |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
90 |
930
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
91 int16_t ams_shift[] = {8, 1, -1, -2}; |
740
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
92 |
362 | 93 #define MAX_ENVELOPE 0xFFC |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
94 #define YM_DIVIDER 2 |
374 | 95 #define CYCLE_NEVER 0xFFFFFFFF |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
96 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
97 static uint16_t round_fixed_point(double value, int dec_bits) |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
98 { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
99 return value * (1 << dec_bits) + 0.5; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
100 } |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
101 |
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 FILE * debug_file = NULL; |
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
103 static uint32_t first_key_on=0; |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
104 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
105 static ym2612_context * log_context = NULL; |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
106 |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
107 static void ym_finalize_log() |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
108 { |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
109 if (!log_context) { |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
110 return; |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
111 } |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
112 for (int i = 0; i < NUM_CHANNELS; i++) { |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
113 if (log_context->channels[i].logfile) { |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
114 wave_finalize(log_context->channels[i].logfile); |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
115 } |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
116 } |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
117 log_context = NULL; |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
118 } |
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
|
119 |
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
|
120 void ym_adjust_master_clock(ym2612_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
|
121 { |
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
|
122 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS); |
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
|
123 } |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
124 |
859
46bb673eed4e
Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents:
853
diff
changeset
|
125 #ifdef __ANDROID__ |
46bb673eed4e
Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents:
853
diff
changeset
|
126 #define log2(x) (log(x)/log(2)) |
46bb673eed4e
Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents:
853
diff
changeset
|
127 #endif |
46bb673eed4e
Load config file and rom.db from appropriate locations on Android
Michael Pavone <pavone@retrodev.com>
parents:
853
diff
changeset
|
128 |
1308
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
129 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
130 #define TIMER_A_MAX 1023 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
131 #define TIMER_B_MAX 255 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
132 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
133 void ym_reset(ym2612_context *context) |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
134 { |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
135 memset(context->part1_regs, 0, sizeof(context->part1_regs)); |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
136 memset(context->part2_regs, 0, sizeof(context->part2_regs)); |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
137 memset(context->operators, 0, sizeof(context->operators)); |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
138 memset(context->channels, 0, sizeof(context->channels)); |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
139 memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
140 context->selected_reg = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
141 context->csm_keyon = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
142 context->ch3_mode = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
143 context->dac_enable = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
144 context->status = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
145 context->timer_a_load = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
146 context->timer_b_load = 0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
147 //TODO: Confirm these on hardware |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
148 context->timer_a = TIMER_A_MAX; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
149 context->timer_b = TIMER_B_MAX; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
150 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
151 //TODO: Reset LFO state |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
152 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
153 //some games seem to expect that the LR flags start out as 1 |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
154 for (int i = 0; i < NUM_CHANNELS; i++) { |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
155 context->channels[i].lr = 0xC0; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
156 } |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
157 context->write_cycle = CYCLE_NEVER; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
158 for (int i = 0; i < NUM_OPERATORS; i++) { |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
159 context->operators[i].envelope = MAX_ENVELOPE; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
160 context->operators[i].env_phase = PHASE_RELEASE; |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
161 } |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
162 } |
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
163 |
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
|
164 void ym_init(ym2612_context * context, uint32_t master_clock, uint32_t clock_div, uint32_t options) |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 { |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
166 static uint8_t registered_finalize; |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
167 dfopen(debug_file, "ym_debug.txt", "w"); |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 memset(context, 0, sizeof(*context)); |
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:
379
diff
changeset
|
169 context->clock_inc = clock_div * 6; |
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
|
170 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); |
1308
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
171 |
369
fc820ab1394b
Fix left/right enable default value
Mike Pavone <pavone@retrodev.com>
parents:
365
diff
changeset
|
172 //some games seem to expect that the LR flags start out as 1 |
fc820ab1394b
Fix left/right enable default value
Mike Pavone <pavone@retrodev.com>
parents:
365
diff
changeset
|
173 for (int i = 0; i < NUM_CHANNELS; i++) { |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
174 if (options & YM_OPT_WAVE_LOG) { |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
175 char fname[64]; |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
176 sprintf(fname, "ym_channel_%d.wav", i); |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
177 FILE * f = context->channels[i].logfile = fopen(fname, "wb"); |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
178 if (!f) { |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
179 fprintf(stderr, "Failed to open WAVE log file %s for writing\n", fname); |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
180 continue; |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
181 } |
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
|
182 if (!wave_init(f, master_clock / (context->clock_inc * NUM_OPERATORS), 16, 1)) { |
407
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
183 fclose(f); |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
184 context->channels[i].logfile = NULL; |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
185 } |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
186 } |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
187 } |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
188 if (options & YM_OPT_WAVE_LOG) { |
c3abc4ada43d
Add support for logging YM2612 channels to WAVE files
Mike Pavone <pavone@retrodev.com>
parents:
406
diff
changeset
|
189 log_context = context; |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
190 if (!registered_finalize) { |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
191 atexit(ym_finalize_log); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
192 registered_finalize = 1; |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
193 } |
369
fc820ab1394b
Fix left/right enable default value
Mike Pavone <pavone@retrodev.com>
parents:
365
diff
changeset
|
194 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
195 if (!did_tbl_init) { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
196 //populate sine table |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
197 for (int32_t i = 0; i < 512; i++) { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
198 double sine = sin( ((double)(i*2+1) / SINE_TABLE_SIZE) * M_PI_2 ); |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
199 |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
200 //table stores 4.8 fixed pointed representation of the base 2 log |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
201 sine_table[i] = round_fixed_point(-log2(sine), 8); |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
202 } |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
203 //populate power table |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
204 for (int32_t i = 0; i < POW_TABLE_SIZE; i++) { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
205 double linear = pow(2, -((double)((i & 0xFF)+1) / 256.0)); |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
206 int32_t tmp = round_fixed_point(linear, 11); |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
207 int32_t shift = (i >> 8) - 2; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
208 if (shift < 0) { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
209 tmp <<= 0-shift; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
210 } else { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
211 tmp >>= shift; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
212 } |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
213 pow_table[i] = tmp; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
214 } |
362 | 215 //populate envelope generator rate table, from small base table |
216 for (int rate = 0; rate < 64; rate++) { | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
217 for (int cycle = 0; cycle < 8; cycle++) { |
362 | 218 uint16_t value; |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
219 if (rate < 2) { |
362 | 220 value = 0; |
365
3ba3b6656fff
Actually save the shifted phase inc after applying the block shift
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
221 } else if (rate >= 60) { |
362 | 222 value = 8; |
365
3ba3b6656fff
Actually save the shifted phase inc after applying the block shift
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
223 } else if (rate < 8) { |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
224 value = rate_table_base[((rate & 6) == 6 ? 16 : 0) + cycle]; |
365
3ba3b6656fff
Actually save the shifted phase inc after applying the block shift
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
225 } else if (rate < 48) { |
362 | 226 value = rate_table_base[(rate & 0x3) * 8 + cycle]; |
227 } else { | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
228 value = rate_table_base[32 + (rate & 0x3) * 8 + cycle] << ((rate - 48) >> 2); |
362 | 229 } |
365
3ba3b6656fff
Actually save the shifted phase inc after applying the block shift
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
230 rate_table[rate * 8 + cycle] = value; |
362 | 231 } |
232 } | |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
233 //populate LFO PM table from small base table |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
234 //seems like there must be a better way to derive this |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
235 for (int freq = 0; freq < 128; freq++) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
236 for (int pms = 0; pms < 8; pms++) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
237 for (int step = 0; step < 32; step++) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
238 int16_t value = 0; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
239 for (int bit = 0x40, shift = 0; bit > 0; bit >>= 1, shift++) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
240 if (freq & bit) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
241 value += lfo_pm_base[pms][(step & 0x8) ? 7-step & 7 : step & 7] >> shift; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
242 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
243 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
244 if (step & 0x10) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
245 value = -value; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
246 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
247 lfo_pm_table[freq * 256 + pms * 32 + step] = value; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
248 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
249 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
250 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
251 } |
1308
1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
Michael Pavone <pavone@retrodev.com>
parents:
1301
diff
changeset
|
252 ym_reset(context); |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
253 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
255 void ym_free(ym2612_context *context) |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
256 { |
1551
ce1f93be0104
Small cleanup to audio interface between emulation code and renderer backend
Michael Pavone <pavone@retrodev.com>
parents:
1450
diff
changeset
|
257 render_free_source(context->audio); |
884
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
258 if (context == log_context) { |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
259 ym_finalize_log(); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
260 } |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
261 free(context); |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
262 } |
252dfd29831d
Selecting a second game from the menu now works
Michael Pavone <pavone@retrodev.com>
parents:
859
diff
changeset
|
263 |
522
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
521
diff
changeset
|
264 #define YM_VOLUME_MULTIPLIER 2 |
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
521
diff
changeset
|
265 #define YM_VOLUME_DIVIDER 3 |
381
7815ebbbd705
Fix modulation shift value
Mike Pavone <pavone@retrodev.com>
parents:
380
diff
changeset
|
266 #define YM_MOD_SHIFT 1 |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
267 |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
268 #define CSM_MODE 0x80 |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
269 |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
270 #define SSG_ENABLE 8 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
271 #define SSG_INVERT 4 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
272 #define SSG_ALTERNATE 2 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
273 #define SSG_HOLD 1 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
274 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
275 #define SSG_CENTER 0x800 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
276 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
277 static void start_envelope(ym_operator *op, ym_channel *channel) |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
278 { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
279 //Deal with "infinite" attack rates |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
280 uint8_t rate = op->rates[PHASE_ATTACK]; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
281 if (rate) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
282 uint8_t ks = channel->keycode >> op->key_scaling;; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
283 rate = rate*2 + ks; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
284 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
285 if (rate >= 62) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
286 op->env_phase = PHASE_DECAY; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
287 op->envelope = 0; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
288 } else { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
289 op->env_phase = PHASE_ATTACK; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
290 } |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
291 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
292 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
293 static void keyon(ym_operator *op, ym_channel *channel) |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
294 { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
295 start_envelope(op, channel); |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
296 op->phase_counter = 0; |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
297 op->inverted = op->ssg & SSG_INVERT; |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
298 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
299 |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
300 static const uint8_t keyon_bits[] = {0x10, 0x40, 0x20, 0x80}; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
301 |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
302 static void keyoff(ym_operator *op) |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
303 { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
304 op->env_phase = PHASE_RELEASE; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
305 if (op->inverted) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
306 //Nemesis says the inversion state doesn't change here, but I don't see how that is observable either way |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
307 op->inverted = 0; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
308 op->envelope = (SSG_CENTER - op->envelope) & MAX_ENVELOPE; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
309 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
310 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
311 |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
312 static void csm_keyoff(ym2612_context *context) |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
313 { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
314 context->csm_keyon = 0; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
315 uint8_t changes = 0xF0 ^ context->channels[2].keyon; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
316 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++) |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
317 { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
318 if (changes & keyon_bits[bit]) { |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
319 keyoff(context->operators + op); |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
320 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
321 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
322 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
323 |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
324 void ym_run(ym2612_context * context, uint32_t to_cycle) |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
325 { |
362 | 326 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); |
327 //TODO: Fix channel update order OR remap channels in register write | |
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:
379
diff
changeset
|
328 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) { |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
329 //Update timers at beginning of 144 cycle period |
403 | 330 if (!context->current_op) { |
331 if (context->timer_control & BIT_TIMERA_ENABLE) { | |
332 if (context->timer_a != TIMER_A_MAX) { | |
333 context->timer_a++; | |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
334 if (context->csm_keyon) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
335 csm_keyoff(context); |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
336 } |
403 | 337 } else { |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
338 if (context->timer_control & BIT_TIMERA_LOAD) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
339 context->timer_control &= ~BIT_TIMERA_LOAD; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
340 } else if (context->timer_control & BIT_TIMERA_OVEREN) { |
403 | 341 context->status |= BIT_STATUS_TIMERA; |
342 } | |
343 context->timer_a = context->timer_a_load; | |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
344 if (!context->csm_keyon && context->ch3_mode == CSM_MODE) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
345 context->csm_keyon = 0xF0; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
346 uint8_t changes = 0xF0 ^ context->channels[2].keyon;; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
347 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++) |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
348 { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
349 if (changes & keyon_bits[bit]) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
350 keyon(context->operators + op, context->channels + 2); |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
351 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
352 } |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
353 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
354 } |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
355 } |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
356 if (!context->sub_timer_b) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
357 if (context->timer_control & BIT_TIMERB_ENABLE) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
358 if (context->timer_b != TIMER_B_MAX) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
359 context->timer_b++; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
360 } else { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
361 if (context->timer_control & BIT_TIMERB_LOAD) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
362 context->timer_control &= ~BIT_TIMERB_LOAD; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
363 } else if (context->timer_control & BIT_TIMERB_OVEREN) { |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
364 context->status |= BIT_STATUS_TIMERB; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
365 } |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
366 context->timer_b = context->timer_b_load; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
367 } |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
368 } |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
369 } |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
370 context->sub_timer_b += 0x10; |
740
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
371 //Update LFO |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
372 if (context->lfo_enable) { |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
373 if (context->lfo_counter) { |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
374 context->lfo_counter--; |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
375 } else { |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
376 context->lfo_counter = lfo_timer_values[context->lfo_freq]; |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
377 context->lfo_am_step += 2; |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
378 context->lfo_am_step &= 0xFE; |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
379 context->lfo_pm_step = context->lfo_am_step / 8; |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
380 } |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
381 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
382 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
383 //Update Envelope Generator |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
384 if (!(context->current_op % 3)) { |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
385 uint32_t env_cyc = context->env_counter; |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
386 uint32_t op = context->current_env_op; |
362 | 387 ym_operator * operator = context->operators + op; |
388 ym_channel * channel = context->channels + op/4; | |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
389 uint8_t rate; |
929
0ee8cfcc06d1
Change where decay to sustain transition happens to match hardware when decay rate is slow or 0
Michael Pavone <pavone@retrodev.com>
parents:
884
diff
changeset
|
390 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) { |
0ee8cfcc06d1
Change where decay to sustain transition happens to match hardware when decay rate is slow or 0
Michael Pavone <pavone@retrodev.com>
parents:
884
diff
changeset
|
391 //operator->envelope = operator->sustain_level; |
0ee8cfcc06d1
Change where decay to sustain transition happens to match hardware when decay rate is slow or 0
Michael Pavone <pavone@retrodev.com>
parents:
884
diff
changeset
|
392 operator->env_phase = PHASE_SUSTAIN; |
0ee8cfcc06d1
Change where decay to sustain transition happens to match hardware when decay rate is slow or 0
Michael Pavone <pavone@retrodev.com>
parents:
884
diff
changeset
|
393 } |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
394 rate = operator->rates[operator->env_phase]; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
395 if (rate) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
396 uint8_t ks = channel->keycode >> operator->key_scaling;; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
397 rate = rate*2 + ks; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
398 if (rate > 63) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
399 rate = 63; |
362 | 400 } |
401 } | |
402 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0; | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
403 if (first_key_on) { |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
404 dfprintf(debug_file, "Operator: %d, env rate: %d (2*%d+%d), env_cyc: %d, cycle_shift: %d, env_cyc & ((1 << cycle_shift) - 1): %d\n", op, rate, operator->rates[operator->env_phase], channel->keycode >> operator->key_scaling,env_cyc, cycle_shift, env_cyc & ((1 << cycle_shift) - 1)); |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
405 } |
362 | 406 if (!(env_cyc & ((1 << cycle_shift) - 1))) { |
407 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7; | |
852
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
408 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle]; |
362 | 409 if (operator->env_phase == PHASE_ATTACK) { |
410 //this can probably be optimized to a single shift rather than a multiply + shift | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
411 if (first_key_on) { |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
412 dfprintf(debug_file, "Changing op %d envelope %d by %d(%d * %d) in attack phase\n", op, operator->envelope, (~operator->envelope * envelope_inc) >> 4, ~operator->envelope, envelope_inc); |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
413 } |
513
24ebabd89162
Properly clamp envelope value to zero when it overflows during the attack phase. This fixes a number of instruments that sounded rather wrong as well as the missing melody line from Mushroom Hill Zone in Sonic and Knuckles
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
414 uint16_t old_env = operator->envelope; |
852
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
415 operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC; |
513
24ebabd89162
Properly clamp envelope value to zero when it overflows during the attack phase. This fixes a number of instruments that sounded rather wrong as well as the missing melody line from Mushroom Hill Zone in Sonic and Knuckles
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
416 if (operator->envelope > old_env) { |
24ebabd89162
Properly clamp envelope value to zero when it overflows during the attack phase. This fixes a number of instruments that sounded rather wrong as well as the missing melody line from Mushroom Hill Zone in Sonic and Knuckles
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
417 //Handle overflow |
24ebabd89162
Properly clamp envelope value to zero when it overflows during the attack phase. This fixes a number of instruments that sounded rather wrong as well as the missing melody line from Mushroom Hill Zone in Sonic and Knuckles
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
418 operator->envelope = 0; |
24ebabd89162
Properly clamp envelope value to zero when it overflows during the attack phase. This fixes a number of instruments that sounded rather wrong as well as the missing melody line from Mushroom Hill Zone in Sonic and Knuckles
Michael Pavone <pavone@retrodev.com>
parents:
505
diff
changeset
|
419 } |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
420 if (!operator->envelope) { |
362 | 421 operator->env_phase = PHASE_DECAY; |
422 } | |
423 } else { | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
424 if (first_key_on) { |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
425 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc, |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
426 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release")); |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
427 } |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
428 if (operator->ssg) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
429 if (operator->envelope < SSG_CENTER) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
430 envelope_inc *= 4; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
431 } else { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
432 envelope_inc = 0; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
433 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
434 } |
852
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
435 //envelope value is 10-bits, but it will be used as a 4.8 value |
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
436 operator->envelope += envelope_inc << 2; |
362 | 437 //clamp to max attenuation value |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
438 if ( |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
439 operator->envelope > MAX_ENVELOPE |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
440 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER) |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
441 ) { |
362 | 442 operator->envelope = MAX_ENVELOPE; |
443 } | |
444 } | |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
445 } |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
446 context->current_env_op++; |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
447 if (context->current_env_op == NUM_OPERATORS) { |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
448 context->current_env_op = 0; |
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
449 context->env_counter++; |
362 | 450 } |
451 } | |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
452 |
362 | 453 //Update Phase Generator |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
454 uint32_t channel = context->current_op / 4; |
362 | 455 if (channel != 5 || !context->dac_enable) { |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
456 uint32_t op = context->current_op; |
362 | 457 //printf("updating operator %d of channel %d\n", op, channel); |
458 ym_operator * operator = context->operators + op; | |
459 ym_channel * chan = context->channels + channel; | |
396
09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
Mike Pavone <pavone@retrodev.com>
parents:
386
diff
changeset
|
460 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
461 operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op); |
371
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
462 int16_t mod = 0; |
362 | 463 switch (op % 4) |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
464 { |
362 | 465 case 0://Operator 1 |
377 | 466 if (chan->feedback) { |
527
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
467 mod = (chan->op1_old + operator->output) >> (10-chan->feedback); |
377 | 468 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
469 break; |
362 | 470 case 1://Operator 3 |
471 switch(chan->algorithm) | |
472 { | |
473 case 0: | |
474 case 2: | |
475 //modulate by operator 2 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
476 mod = context->operators[op+1].output >> YM_MOD_SHIFT; |
362 | 477 break; |
478 case 1: | |
479 //modulate by operator 1+2 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
480 mod = (context->operators[op-1].output + context->operators[op+1].output) >> YM_MOD_SHIFT; |
362 | 481 break; |
482 case 5: | |
483 //modulate by operator 1 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
484 mod = context->operators[op-1].output >> YM_MOD_SHIFT; |
362 | 485 } |
486 break; | |
487 case 2://Operator 2 | |
406
b1bc1947d949
Fix modulation condition for operator 2
Mike Pavone <pavone@retrodev.com>
parents:
403
diff
changeset
|
488 if (chan->algorithm != 1 && chan->algorithm != 2 && chan->algorithm != 7) { |
362 | 489 //modulate by Operator 1 |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
490 mod = context->operators[op-2].output >> YM_MOD_SHIFT; |
362 | 491 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
492 break; |
362 | 493 case 3://Operator 4 |
494 switch(chan->algorithm) | |
495 { | |
496 case 0: | |
497 case 1: | |
498 case 4: | |
499 //modulate by operator 3 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
500 mod = context->operators[op-2].output >> YM_MOD_SHIFT; |
362 | 501 break; |
502 case 2: | |
503 //modulate by operator 1+3 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
504 mod = (context->operators[op-3].output + context->operators[op-2].output) >> YM_MOD_SHIFT; |
362 | 505 break; |
506 case 3: | |
507 //modulate by operator 2+3 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
508 mod = (context->operators[op-1].output + context->operators[op-2].output) >> YM_MOD_SHIFT; |
362 | 509 break; |
510 case 5: | |
511 //modulate by operator 1 | |
379
3218e2f8d685
Make shift value of operator output to modulation input a define
Mike Pavone <pavone@retrodev.com>
parents:
378
diff
changeset
|
512 mod = context->operators[op-3].output >> YM_MOD_SHIFT; |
362 | 513 break; |
514 } | |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
515 break; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
516 } |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
517 uint16_t env = operator->envelope; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
518 if (operator->ssg) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
519 if (env >= SSG_CENTER) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
520 if (operator->ssg & SSG_ALTERNATE) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
521 if (operator->env_phase != PHASE_RELEASE && ( |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
522 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0 |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
523 )) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
524 operator->inverted ^= SSG_INVERT; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
525 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
526 } else if (!(operator->ssg & SSG_HOLD)) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
527 phase = operator->phase_counter = 0; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
528 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
529 if ( |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
530 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN) |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
531 && !(operator->ssg & SSG_HOLD) |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
532 ) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
533 start_envelope(operator, chan); |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
534 env = operator->envelope; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
535 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
536 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
537 if (operator->inverted) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
538 env = (SSG_CENTER - env) & MAX_ENVELOPE; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
539 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
540 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
541 env += operator->total_level; |
740
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
542 if (operator->am) { |
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
543 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E; |
930
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
544 if (ams_shift[chan->ams] >= 0) { |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
545 env += base_am >> ams_shift[chan->ams]; |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
546 } else { |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
547 env += base_am << (-ams_shift[chan->ams]); |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
548 } |
740
25c9e9d39997
Fix LFO counter update speed and implement amplitude modulation
Michael Pavone <pavone@retrodev.com>
parents:
739
diff
changeset
|
549 } |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
550 if (env > MAX_ENVELOPE) { |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
551 env = MAX_ENVELOPE; |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
552 } |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
553 if (first_key_on) { |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
554 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]); |
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
555 } |
527
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
556 //if ((channel != 0 && channel != 4) || chan->algorithm != 5) { |
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
557 phase += mod; |
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
558 //} |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
559 |
371
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
560 int16_t output = pow_table[sine_table[phase & 0x1FF] + env]; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
561 if (phase & 0x200) { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
562 output = -output; |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
563 } |
527
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
564 if (op % 4 == 0) { |
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
565 chan->op1_old = operator->output; |
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
566 } |
362 | 567 operator->output = output; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
568 //Update the channel output if we've updated all operators |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
569 if (op % 4 == 3) { |
362 | 570 if (chan->algorithm < 4) { |
571 chan->output = operator->output; | |
572 } else if(chan->algorithm == 4) { | |
396
09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
Mike Pavone <pavone@retrodev.com>
parents:
386
diff
changeset
|
573 chan->output = operator->output + context->operators[channel * 4 + 2].output; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
574 } else { |
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
575 output = 0; |
362 | 576 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { |
577 output += context->operators[op].output; | |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
578 } |
362 | 579 chan->output = output; |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
580 } |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
581 if (first_key_on) { |
371
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
582 int16_t value = context->channels[channel].output & 0x3FE0; |
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
583 if (value & 0x2000) { |
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
584 value |= 0xC000; |
0f8a759f1ff4
Use signed ints for things that represent signed values in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
370
diff
changeset
|
585 } |
522
6a14c5a95648
Adjust PSG and YM-2612 volume to be closer to the real console
Michael Pavone <pavone@retrodev.com>
parents:
521
diff
changeset
|
586 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER); |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
587 } |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
588 } |
362 | 589 //puts("operator update done"); |
359
cc39629e8d06
YM2612 WIP snapshot before register refactor
Mike Pavone <pavone@retrodev.com>
parents:
288
diff
changeset
|
590 } |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
591 context->current_op++; |
396
09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
Mike Pavone <pavone@retrodev.com>
parents:
386
diff
changeset
|
592 if (context->current_op == NUM_OPERATORS) { |
09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
Mike Pavone <pavone@retrodev.com>
parents:
386
diff
changeset
|
593 context->current_op = 0; |
965
5257e85364ed
Implemented linear resampling and low pass filter for the YM2612
Michael Pavone <pavone@retrodev.com>
parents:
936
diff
changeset
|
594 |
5257e85364ed
Implemented linear resampling and low pass filter for the YM2612
Michael Pavone <pavone@retrodev.com>
parents:
936
diff
changeset
|
595 int16_t left = 0, right = 0; |
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
|
596 for (int i = 0; i < NUM_CHANNELS; i++) { |
521
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
597 int16_t value = context->channels[i].output; |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
598 if (value > 0x1FE0) { |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
599 value = 0x1FE0; |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
600 } else if (value < -0x1FF0) { |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
601 value = -0x1FF0; |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
602 } else { |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
603 value &= 0x3FE0; |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
604 if (value & 0x2000) { |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
605 value |= 0xC000; |
7565ec2ac652
Fix overflow handling on FM channel output
Michael Pavone <pavone@retrodev.com>
parents:
513
diff
changeset
|
606 } |
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:
379
diff
changeset
|
607 } |
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
|
608 if (context->channels[i].logfile) { |
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
|
609 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); |
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
|
610 } |
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
|
611 if (context->channels[i].lr & 0x80) { |
965
5257e85364ed
Implemented linear resampling and low pass filter for the YM2612
Michael Pavone <pavone@retrodev.com>
parents:
936
diff
changeset
|
612 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; |
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:
379
diff
changeset
|
613 } |
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
|
614 if (context->channels[i].lr & 0x40) { |
965
5257e85364ed
Implemented linear resampling and low pass filter for the YM2612
Michael Pavone <pavone@retrodev.com>
parents:
936
diff
changeset
|
615 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; |
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
|
616 } |
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
|
617 } |
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
|
618 render_put_stereo_sample(context->audio, left, right); |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
619 } |
965
5257e85364ed
Implemented linear resampling and low pass filter for the YM2612
Michael Pavone <pavone@retrodev.com>
parents:
936
diff
changeset
|
620 |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
621 } |
535
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
622 if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) { |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
623 context->status &= 0x7F; |
374 | 624 context->write_cycle = CYCLE_NEVER; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
625 } |
362 | 626 //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle); |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
627 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
628 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
629 void ym_address_write_part1(ym2612_context * context, uint8_t address) |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
630 { |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
631 //printf("address_write_part1: %X\n", address); |
362 | 632 context->selected_reg = address; |
633 context->selected_part = 0; | |
535
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
634 context->write_cycle = context->current_cycle; |
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
635 context->busy_cycles = BUSY_CYCLES_ADDRESS; |
650
55b550fe8891
Set the busy flag after a YM-2612 address write
Michael Pavone <pavone@retrodev.com>
parents:
535
diff
changeset
|
636 context->status |= 0x80; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
637 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
638 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
639 void ym_address_write_part2(ym2612_context * context, uint8_t address) |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
640 { |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
641 //printf("address_write_part2: %X\n", address); |
362 | 642 context->selected_reg = address; |
643 context->selected_part = 1; | |
535
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
644 context->write_cycle = context->current_cycle; |
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
645 context->busy_cycles = BUSY_CYCLES_ADDRESS; |
650
55b550fe8891
Set the busy flag after a YM-2612 address write
Michael Pavone <pavone@retrodev.com>
parents:
535
diff
changeset
|
646 context->status |= 0x80; |
362 | 647 } |
648 | |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
649 static uint8_t fnum_to_keycode[] = { |
362 | 650 //F11 = 0 |
651 0,0,0,0,0,0,0,1, | |
652 //F11 = 1 | |
653 2,3,3,3,3,3,3,3 | |
654 }; | |
655 | |
656 //table courtesy of Nemesis | |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
657 static uint32_t detune_table[][4] = { |
362 | 658 {0, 0, 1, 2}, //0 (0x00) |
659 {0, 0, 1, 2}, //1 (0x01) | |
660 {0, 0, 1, 2}, //2 (0x02) | |
661 {0, 0, 1, 2}, //3 (0x03) | |
662 {0, 1, 2, 2}, //4 (0x04) | |
663 {0, 1, 2, 3}, //5 (0x05) | |
664 {0, 1, 2, 3}, //6 (0x06) | |
665 {0, 1, 2, 3}, //7 (0x07) | |
666 {0, 1, 2, 4}, //8 (0x08) | |
667 {0, 1, 3, 4}, //9 (0x09) | |
668 {0, 1, 3, 4}, //10 (0x0A) | |
669 {0, 1, 3, 5}, //11 (0x0B) | |
670 {0, 2, 4, 5}, //12 (0x0C) | |
671 {0, 2, 4, 6}, //13 (0x0D) | |
672 {0, 2, 4, 6}, //14 (0x0E) | |
673 {0, 2, 5, 7}, //15 (0x0F) | |
674 {0, 2, 5, 8}, //16 (0x10) | |
675 {0, 3, 6, 8}, //17 (0x11) | |
676 {0, 3, 6, 9}, //18 (0x12) | |
677 {0, 3, 7,10}, //19 (0x13) | |
678 {0, 4, 8,11}, //20 (0x14) | |
679 {0, 4, 8,12}, //21 (0x15) | |
680 {0, 4, 9,13}, //22 (0x16) | |
681 {0, 5,10,14}, //23 (0x17) | |
682 {0, 5,11,16}, //24 (0x18) | |
683 {0, 6,12,17}, //25 (0x19) | |
684 {0, 6,13,19}, //26 (0x1A) | |
685 {0, 7,14,20}, //27 (0x1B) | |
686 {0, 8,16,22}, //28 (0x1C) | |
687 {0, 8,16,22}, //29 (0x1D) | |
688 {0, 8,16,22}, //30 (0x1E) | |
689 {0, 8,16,22} | |
690 }; //31 (0x1F) | |
691 | |
1102
c15896605bf2
Clean up symbol visiblity and delete a ltitle bit of dead code
Michael Pavone <pavone@retrodev.com>
parents:
1002
diff
changeset
|
692 static uint32_t ym_calc_phase_inc(ym2612_context * context, ym_operator * operator, uint32_t op) |
362 | 693 { |
694 uint32_t chan_num = op / 4; | |
695 //printf("ym_update_phase_inc | channel: %d, op: %d\n", chan_num, op); | |
696 //base frequency | |
697 ym_channel * channel = context->channels + chan_num; | |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
698 uint32_t inc, detune; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
699 if (chan_num == 2 && context->ch3_mode && (op < (2*4 + 3))) { |
738
8972378e314f
Fix register to operator mapping for channel 3 special mode
Michael Pavone <pavone@retrodev.com>
parents:
650
diff
changeset
|
700 //supplemental fnum registers are in a different order than normal slot paramters |
936
f1a8124ad881
Fix register to operator mapping for channel 3 special mode and actually get it right this time
Michael Pavone <pavone@retrodev.com>
parents:
935
diff
changeset
|
701 int index = op-2*4; |
f1a8124ad881
Fix register to operator mapping for channel 3 special mode and actually get it right this time
Michael Pavone <pavone@retrodev.com>
parents:
935
diff
changeset
|
702 if (index < 2) { |
f1a8124ad881
Fix register to operator mapping for channel 3 special mode and actually get it right this time
Michael Pavone <pavone@retrodev.com>
parents:
935
diff
changeset
|
703 index ^= 1; |
f1a8124ad881
Fix register to operator mapping for channel 3 special mode and actually get it right this time
Michael Pavone <pavone@retrodev.com>
parents:
935
diff
changeset
|
704 } |
738
8972378e314f
Fix register to operator mapping for channel 3 special mode
Michael Pavone <pavone@retrodev.com>
parents:
650
diff
changeset
|
705 inc = context->ch3_supp[index].fnum; |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
706 if (channel->pms) { |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
707 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
708 } |
738
8972378e314f
Fix register to operator mapping for channel 3 special mode
Michael Pavone <pavone@retrodev.com>
parents:
650
diff
changeset
|
709 if (!context->ch3_supp[index].block) { |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
710 inc >>= 1; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
711 } else { |
738
8972378e314f
Fix register to operator mapping for channel 3 special mode
Michael Pavone <pavone@retrodev.com>
parents:
650
diff
changeset
|
712 inc <<= (context->ch3_supp[index].block-1); |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
713 } |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
714 //detune |
738
8972378e314f
Fix register to operator mapping for channel 3 special mode
Michael Pavone <pavone@retrodev.com>
parents:
650
diff
changeset
|
715 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
716 } else { |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
717 inc = channel->fnum; |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
718 if (channel->pms) { |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
719 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
720 } |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
721 if (!channel->block) { |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
722 inc >>= 1; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
723 } else { |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
724 inc <<= (channel->block-1); |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
725 } |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
726 //detune |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
727 detune = detune_table[channel->keycode][operator->detune & 0x3]; |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
728 } |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
729 if (channel->pms) { |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
730 inc >>= 1; |
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
731 } |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
732 if (operator->detune & 0x4) { |
362 | 733 inc -= detune; |
734 //this can underflow, mask to 17-bit result | |
735 inc &= 0x1FFFF; | |
736 } else { | |
737 inc += detune; | |
738 } | |
739 //multiple | |
740 if (operator->multiple) { | |
741 inc *= operator->multiple; | |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
742 inc &= 0xFFFFF; |
362 | 743 } else { |
744 //0.5 | |
745 inc >>= 1; | |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
746 } |
365
3ba3b6656fff
Actually save the shifted phase inc after applying the block shift
Mike Pavone <pavone@retrodev.com>
parents:
364
diff
changeset
|
747 //printf("phase_inc for operator %d: %d, block: %d, fnum: %d, detune: %d, multiple: %d\n", op, inc, channel->block, channel->fnum, detune, operator->multiple); |
935
01fb50390b27
Remove phase increment caching. Fix LFO phase modulation calculation
Michael Pavone <pavone@retrodev.com>
parents:
930
diff
changeset
|
748 return inc; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
749 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
750 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
751 void ym_data_write(ym2612_context * context, uint8_t value) |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
752 { |
451
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
753 if (context->selected_reg >= YM_REG_END) { |
362 | 754 return; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
755 } |
451
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
756 if (context->selected_part) { |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
757 if (context->selected_reg < YM_PART2_START) { |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
758 return; |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
759 } |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
760 context->part2_regs[context->selected_reg - YM_PART2_START] = value; |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
761 } else { |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
762 if (context->selected_reg < YM_PART1_START) { |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
763 return; |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
764 } |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
765 context->part1_regs[context->selected_reg - YM_PART1_START] = value; |
b7c3b2d22858
Added support for saving savestates. Added gst savestate format test harness
Mike Pavone <pavone@retrodev.com>
parents:
448
diff
changeset
|
766 } |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
767 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1); |
362 | 768 if (context->selected_reg < 0x30) { |
769 //Shared regs | |
770 switch (context->selected_reg) | |
771 { | |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
772 //TODO: Test reg |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
773 case REG_LFO: |
532
666210adf87b
Comment out LFO debug printf
Mike Pavone <pavone@retrodev.com>
parents:
527
diff
changeset
|
774 /*if ((value & 0x8) && !context->lfo_enable) { |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
775 printf("LFO Enabled, Freq: %d\n", value & 0x7); |
532
666210adf87b
Comment out LFO debug printf
Mike Pavone <pavone@retrodev.com>
parents:
527
diff
changeset
|
776 }*/ |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
777 context->lfo_enable = value & 0x8; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
778 if (!context->lfo_enable) { |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
779 context->lfo_am_step = context->lfo_pm_step = 0; |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
780 } |
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
781 context->lfo_freq = value & 0x7; |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
782 |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
783 break; |
362 | 784 case REG_TIMERA_HIGH: |
785 context->timer_a_load &= 0x3; | |
786 context->timer_a_load |= value << 2; | |
787 break; | |
788 case REG_TIMERA_LOW: | |
789 context->timer_a_load &= 0xFFFC; | |
790 context->timer_a_load |= value & 0x3; | |
791 break; | |
792 case REG_TIMERB: | |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
793 context->timer_b_load = value; |
362 | 794 break; |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
795 case REG_TIME_CTRL: { |
403 | 796 if (value & BIT_TIMERA_ENABLE && !(context->timer_control & BIT_TIMERA_ENABLE)) { |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
797 context->timer_a = TIMER_A_MAX; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
798 context->timer_control |= BIT_TIMERA_LOAD; |
403 | 799 } |
800 if (value & BIT_TIMERB_ENABLE && !(context->timer_control & BIT_TIMERB_ENABLE)) { | |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
801 context->timer_b = TIMER_B_MAX; |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
802 context->timer_control |= BIT_TIMERB_LOAD; |
403 | 803 } |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
804 context->timer_control &= (BIT_TIMERA_LOAD | BIT_TIMERB_LOAD); |
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
805 context->timer_control |= value & 0xF; |
403 | 806 if (value & BIT_TIMERA_RESET) { |
807 context->status &= ~BIT_STATUS_TIMERA; | |
808 } | |
809 if (value & BIT_TIMERB_RESET) { | |
810 context->status &= ~BIT_STATUS_TIMERB; | |
811 } | |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
812 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
813 csm_keyoff(context); |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
814 } |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
815 context->ch3_mode = value & 0xC0; |
362 | 816 break; |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
817 } |
362 | 818 case REG_KEY_ONOFF: { |
819 uint8_t channel = value & 0x7; | |
386
6e5c4f3ab0e2
Fix channel mapping in key on/off register
Mike Pavone <pavone@retrodev.com>
parents:
383
diff
changeset
|
820 if (channel != 3 && channel != 7) { |
6e5c4f3ab0e2
Fix channel mapping in key on/off register
Mike Pavone <pavone@retrodev.com>
parents:
383
diff
changeset
|
821 if (channel > 2) { |
6e5c4f3ab0e2
Fix channel mapping in key on/off register
Mike Pavone <pavone@retrodev.com>
parents:
383
diff
changeset
|
822 channel--; |
6e5c4f3ab0e2
Fix channel mapping in key on/off register
Mike Pavone <pavone@retrodev.com>
parents:
383
diff
changeset
|
823 } |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
824 uint8_t changes = channel == 2 |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
825 ? (value | context->csm_keyon) ^ (context->channels[channel].keyon | context->csm_keyon) |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
826 : value ^ context->channels[channel].keyon; |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
827 context->channels[channel].keyon = value & 0xF0; |
851
b10cf2c921ad
Fix mapping of key on/off reg bits to operators
Michael Pavone <pavone@retrodev.com>
parents:
848
diff
changeset
|
828 for (uint8_t op = channel * 4, bit = 0; op < (channel + 1) * 4; op++, bit++) { |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
829 if (changes & keyon_bits[bit]) { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
830 if (value & keyon_bits[bit]) { |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
831 first_key_on = 1; |
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
832 //printf("Key On for operator %d in channel %d\n", op, channel); |
1300
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
833 keyon(context->operators + op, context->channels + channel); |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
834 } else { |
4b893b02444e
Basic implementation of CSM mode that should handle documented edge cases. Dodesn't handle the weird undocumented edge cases I don't have a good understanding of yet though
Michael Pavone <pavone@retrodev.com>
parents:
1102
diff
changeset
|
835 //printf("Key Off for operator %d in channel %d\n", op, channel); |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
836 keyoff(context->operators + op); |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
837 } |
362 | 838 } |
839 } | |
840 } | |
841 break; | |
842 } | |
843 case REG_DAC: | |
844 if (context->dac_enable) { | |
845 context->channels[5].output = (((int16_t)value) - 0x80) << 6; | |
396
09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
Mike Pavone <pavone@retrodev.com>
parents:
386
diff
changeset
|
846 //printf("DAC Write %X(%d) @ %d\n", value, context->channels[5].output, context->current_cycle); |
362 | 847 } |
848 break; | |
849 case REG_DAC_ENABLE: | |
364
62177cc39049
Incredibly broken YM2612 support plus a fix to Z80 bus request
Mike Pavone <pavone@retrodev.com>
parents:
362
diff
changeset
|
850 //printf("DAC Enable: %X\n", value); |
362 | 851 context->dac_enable = value & 0x80; |
852 break; | |
853 } | |
854 } else if (context->selected_reg < 0xA0) { | |
855 //part | |
856 uint8_t op = context->selected_part ? (NUM_OPERATORS/2) : 0; | |
857 //channel in part | |
858 if ((context->selected_reg & 0x3) != 0x3) { | |
370
5f215603d001
Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
Mike Pavone <pavone@retrodev.com>
parents:
369
diff
changeset
|
859 op += 4 * (context->selected_reg & 0x3) + ((context->selected_reg & 0xC) / 4); |
362 | 860 //printf("write targets operator %d (%d of channel %d)\n", op, op % 4, op / 4); |
861 ym_operator * operator = context->operators + op; | |
862 switch (context->selected_reg & 0xF0) | |
863 { | |
864 case REG_DETUNE_MULT: | |
865 operator->detune = value >> 4 & 0x7; | |
866 operator->multiple = value & 0xF; | |
867 break; | |
868 case REG_TOTAL_LEVEL: | |
869 operator->total_level = (value & 0x7F) << 5; | |
870 break; | |
871 case REG_ATTACK_KS: | |
376 | 872 operator->key_scaling = 3 - (value >> 6); |
362 | 873 operator->rates[PHASE_ATTACK] = value & 0x1F; |
874 break; | |
875 case REG_DECAY_AM: | |
876 //TODO: AM flag for LFO | |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
877 operator->am = value & 0x80; |
362 | 878 operator->rates[PHASE_DECAY] = value & 0x1F; |
879 break; | |
880 case REG_SUSTAIN_RATE: | |
881 operator->rates[PHASE_SUSTAIN] = value & 0x1F; | |
882 break; | |
883 case REG_S_LVL_R_RATE: | |
884 operator->rates[PHASE_RELEASE] = (value & 0xF) << 1 | 1; | |
852
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
885 operator->sustain_level = (value & 0xF0) << 3; |
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
886 if (operator->sustain_level == 0x780) { |
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
887 operator->sustain_level = MAX_ENVELOPE; |
5de8759b87af
Fix some bugs in the attack phase and sustain level in the envelope generator
Michael Pavone <pavone@retrodev.com>
parents:
851
diff
changeset
|
888 } |
362 | 889 break; |
1301
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
890 case REG_SSG_EG: |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
891 if (!(value & SSG_ENABLE)) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
892 value = 0; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
893 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
894 if ((value ^ operator->ssg) & SSG_INVERT) { |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
895 operator->inverted ^= SSG_INVERT; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
896 } |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
897 operator->ssg = value; |
babff81e4cfd
Initial implementation of YM2612 SSG-EG mode
Michael Pavone <pavone@retrodev.com>
parents:
1300
diff
changeset
|
898 break; |
362 | 899 } |
900 } | |
901 } else { | |
902 uint8_t channel = context->selected_reg & 0x3; | |
903 if (channel != 3) { | |
904 if (context->selected_part) { | |
905 channel += 3; | |
906 } | |
907 //printf("write targets channel %d\n", channel); | |
908 switch (context->selected_reg & 0xFC) | |
909 { | |
910 case REG_FNUM_LOW: | |
911 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7; | |
912 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value; | |
913 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7]; | |
914 break; | |
915 case REG_BLOCK_FNUM_H:{ | |
916 context->channels[channel].block_fnum_latch = value; | |
917 break; | |
918 } | |
383
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
919 case REG_FNUM_LOW_CH3: |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
920 if (channel < 3) { |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
921 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
922 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
923 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
924 } |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
925 break; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
926 case REG_BLOCK_FN_CH3: |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
927 if (channel < 3) { |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
928 context->ch3_supp[channel].block_fnum_latch = value; |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
929 } |
72933100c55c
Initial implementation of channel 3 special mode
Mike Pavone <pavone@retrodev.com>
parents:
382
diff
changeset
|
930 break; |
362 | 931 case REG_ALG_FEEDBACK: |
932 context->channels[channel].algorithm = value & 0x7; | |
933 context->channels[channel].feedback = value >> 3 & 0x7; | |
527
7df7f493b3b6
Fix operator 1 self-feedback
Michael Pavone <pavone@retrodev.com>
parents:
522
diff
changeset
|
934 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); |
362 | 935 break; |
936 case REG_LR_AMS_PMS: | |
411
baf4688901f2
Initial stab at LFO phase modulation
Mike Pavone <pavone@retrodev.com>
parents:
407
diff
changeset
|
937 context->channels[channel].pms = (value & 0x7) * 32; |
362 | 938 context->channels[channel].ams = value >> 4 & 0x3; |
939 context->channels[channel].lr = value & 0xC0; | |
369
fc820ab1394b
Fix left/right enable default value
Mike Pavone <pavone@retrodev.com>
parents:
365
diff
changeset
|
940 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); |
362 | 941 break; |
942 } | |
943 } | |
944 } | |
448
e85a107e6ec0
Fix handling of key on in YM2612 core
Mike Pavone <pavone@retrodev.com>
parents:
424
diff
changeset
|
945 |
362 | 946 context->write_cycle = context->current_cycle; |
535
aaa77e351c24
Better emulation of the YM-2612 busy flag
Mike Pavone <pavone@retrodev.com>
parents:
532
diff
changeset
|
947 context->busy_cycles = context->selected_reg < 0xA0 ? BUSY_CYCLES_DATA_LOW : BUSY_CYCLES_DATA_HIGH; |
374 | 948 context->status |= 0x80; |
288
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
949 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
950 |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
951 uint8_t ym_read_status(ym2612_context * context) |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
952 { |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
953 return context->status; |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
954 } |
a8ee7934a1f8
Add a YM2612 stub implementation with just timers and status registers so that games that depend on it can run.
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
955 |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
956 void ym_print_channel_info(ym2612_context *context, int channel) |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
957 { |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
958 ym_channel *chan = context->channels + channel; |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
959 printf("\n***Channel %d***\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
960 "Algorithm: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
961 "Feedback: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
962 "Pan: %s\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
963 "AMS: %d\n" |
845
3a18b5f63afc
Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
Michael Pavone <pavone@retrodev.com>
parents:
740
diff
changeset
|
964 "PMS: %d\n", |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
965 channel+1, chan->algorithm, chan->feedback, |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
966 chan->lr == 0xC0 ? "LR" : chan->lr == 0x80 ? "L" : chan->lr == 0x40 ? "R" : "", |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
967 chan->ams, chan->pms); |
930
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
968 if (channel == 2) { |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
969 printf( |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
970 "Mode: %X: %s\n", |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
971 context->ch3_mode, context->ch3_mode ? "special" : "normal"); |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
972 } |
739
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
973 for (int operator = channel * 4; operator < channel * 4+4; operator++) |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
974 { |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
975 int dispnum = operator - channel * 4 + 1; |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
976 if (dispnum == 2) { |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
977 dispnum = 3; |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
978 } else if (dispnum == 3) { |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
979 dispnum = 2; |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
980 } |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
981 ym_operator *op = context->operators + operator; |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
982 printf("\nOperator %d:\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
983 " Multiple: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
984 " Detune: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
985 " Total Level: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
986 " Attack Rate: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
987 " Key Scaling: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
988 " Decay Rate: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
989 " Sustain Level: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
990 " Sustain Rate: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
991 " Release Rate: %d\n" |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
992 " Amplitude Modulation %s\n", |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
993 dispnum, op->multiple, op->detune, op->total_level, |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
994 op->rates[PHASE_ATTACK], op->key_scaling, op->rates[PHASE_DECAY], |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
995 op->sustain_level, op->rates[PHASE_SUSTAIN], op->rates[PHASE_RELEASE], |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
996 op->am ? "On" : "Off"); |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
997 } |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
998 } |
2317bdca03b4
Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation
Michael Pavone <pavone@retrodev.com>
parents:
738
diff
changeset
|
999 |
930
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1000 void ym_print_timer_info(ym2612_context *context) |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1001 { |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1002 printf("***Timer A***\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1003 "Current Value: %d\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1004 "Load Value: %d\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1005 "Triggered: %s\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1006 "Enabled: %s\n\n", |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1007 context->timer_a, |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1008 context->timer_a_load, |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1009 context->status & BIT_STATUS_TIMERA ? "yes" : "no", |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1010 context->timer_control & BIT_TIMERA_ENABLE ? "yes" : "no"); |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1011 printf("***Timer B***\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1012 "Current Value: %d\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1013 "Load Value: %d\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1014 "Triggered: %s\n" |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1015 "Enabled: %s\n\n", |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1016 context->timer_b, |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1017 context->timer_b_load, |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1018 context->status & BIT_STATUS_TIMERB ? "yes" : "no", |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1019 context->timer_control & BIT_TIMERB_ENABLE ? "yes" : "no"); |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1020 } |
f33e8d88ab6f
Add yt debug command for printing YM-2612 timer info. Fix AMS shift values.
Michael Pavone <pavone@retrodev.com>
parents:
929
diff
changeset
|
1021 |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1022 void ym_serialize(ym2612_context *context, serialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1023 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1024 save_buffer8(buf, context->part1_regs, YM_PART1_REGS); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1025 save_buffer8(buf, context->part2_regs, YM_PART2_REGS); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1026 for (int i = 0; i < NUM_OPERATORS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1027 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1028 save_int32(buf, context->operators[i].phase_counter); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1029 save_int16(buf, context->operators[i].envelope); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1030 save_int16(buf, context->operators[i].output); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1031 save_int8(buf, context->operators[i].env_phase); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1032 save_int8(buf, context->operators[i].inverted); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1033 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1034 for (int i = 0; i < NUM_CHANNELS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1035 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1036 save_int16(buf, context->channels[i].output); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1037 save_int16(buf, context->channels[i].op1_old); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1038 //Due to the latching behavior, these need to be saved |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1039 //even though duplicate info is probably in the regs array |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1040 save_int8(buf, context->channels[i].block); |
1450
08bc099a622f
Save entirety of fnum register, not just the low 8 bits
Michael Pavone <pavone@retrodev.com>
parents:
1447
diff
changeset
|
1041 save_int16(buf, context->channels[i].fnum); |
1447
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1042 save_int8(buf, context->channels[i].keyon); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1043 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1044 for (int i = 0; i < 3; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1045 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1046 //Due to the latching behavior, these need to be saved |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1047 //even though duplicate info is probably in the regs array |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1048 save_int8(buf, context->ch3_supp[i].block); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1049 save_int8(buf, context->ch3_supp[i].fnum); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1050 } |
1447
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1051 save_int8(buf, context->timer_control); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1052 save_int16(buf, context->timer_a); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1053 save_int8(buf, context->timer_b); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1054 save_int8(buf, context->sub_timer_b); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1055 save_int16(buf, context->env_counter); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1056 save_int8(buf, context->current_op); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1057 save_int8(buf, context->current_env_op); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1058 save_int8(buf, context->lfo_counter); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1059 save_int8(buf, context->csm_keyon); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1060 save_int8(buf, context->status); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1061 save_int8(buf, context->selected_reg); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1062 save_int8(buf, context->selected_part); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1063 save_int32(buf, context->current_cycle); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1064 save_int32(buf, context->write_cycle); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1065 save_int32(buf, context->busy_cycles); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1066 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1067 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1068 void ym_deserialize(deserialize_buffer *buf, void *vcontext) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1069 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1070 ym2612_context *context = vcontext; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1071 uint8_t temp_regs[YM_PART1_REGS]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1072 load_buffer8(buf, temp_regs, YM_PART1_REGS); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1073 context->selected_part = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1074 for (int i = 0; i < YM_PART1_REGS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1075 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1076 uint8_t reg = YM_PART1_START + i; |
1447
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1077 if (reg == REG_TIME_CTRL) { |
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1078 context->ch3_mode = temp_regs[i] & 0xC0; |
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1079 } else if (reg != REG_FNUM_LOW && reg != REG_KEY_ONOFF) { |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1080 context->selected_reg = reg; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1081 ym_data_write(context, temp_regs[i]); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1082 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1083 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1084 load_buffer8(buf, temp_regs, YM_PART2_REGS); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1085 context->selected_part = 1; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1086 for (int i = 0; i < YM_PART2_REGS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1087 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1088 uint8_t reg = YM_PART2_START + i; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1089 if (reg != REG_FNUM_LOW) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1090 context->selected_reg = reg; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1091 ym_data_write(context, temp_regs[i]); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1092 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1093 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1094 for (int i = 0; i < NUM_OPERATORS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1095 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1096 context->operators[i].phase_counter = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1097 context->operators[i].envelope = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1098 context->operators[i].output = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1099 context->operators[i].env_phase = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1100 if (context->operators[i].env_phase > PHASE_RELEASE) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1101 context->operators[i].env_phase = PHASE_RELEASE; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1102 } |
1450
08bc099a622f
Save entirety of fnum register, not just the low 8 bits
Michael Pavone <pavone@retrodev.com>
parents:
1447
diff
changeset
|
1103 context->operators[i].inverted = load_int8(buf) != 0 ? SSG_INVERT : 0; |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1104 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1105 for (int i = 0; i < NUM_CHANNELS; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1106 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1107 context->channels[i].output = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1108 context->channels[i].op1_old = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1109 context->channels[i].block = load_int8(buf); |
1450
08bc099a622f
Save entirety of fnum register, not just the low 8 bits
Michael Pavone <pavone@retrodev.com>
parents:
1447
diff
changeset
|
1110 context->channels[i].fnum = load_int16(buf); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1111 context->channels[i].keycode = context->channels[i].block << 2 | fnum_to_keycode[context->channels[i].fnum >> 7]; |
1447
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1112 context->channels[i].keyon = load_int8(buf); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1113 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1114 for (int i = 0; i < 3; i++) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1115 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1116 context->ch3_supp[i].block = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1117 context->ch3_supp[i].fnum = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1118 context->ch3_supp[i].keycode = context->ch3_supp[i].block << 2 | fnum_to_keycode[context->ch3_supp[i].fnum >> 7]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1119 } |
1447
a094815b1168
Save and restore YM2612 timer control and keyon/off state in native save states
Michael Pavone <pavone@retrodev.com>
parents:
1427
diff
changeset
|
1120 context->timer_control = load_int8(buf); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1121 context->timer_a = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1122 context->timer_b = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1123 context->sub_timer_b = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1124 context->env_counter = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1125 context->current_op = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1126 if (context->current_op >= NUM_OPERATORS) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1127 context->current_op = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1128 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1129 context->current_env_op = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1130 if (context->current_env_op >= NUM_OPERATORS) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1131 context->current_env_op = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1132 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1133 context->lfo_counter = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1134 context->csm_keyon = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1135 context->status = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1136 context->selected_reg = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1137 context->selected_part = load_int8(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1138 context->current_cycle = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1139 context->write_cycle = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1140 context->busy_cycles = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
1356
diff
changeset
|
1141 } |