annotate ymf262.c @ 2688:b42f00a3a937 default tip

Fix default target. Ensure m68k.h and z80.h are built before anything else when no dep info is available
author Michael Pavone <pavone@retrodev.com>
date Mon, 31 Mar 2025 21:06:18 -0700
parents eb588f22ec76
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <stdlib.h>
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <string.h>
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #include "ymf262.h"
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include "render_audio.h"
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 void ymf262_init(ymf262_context *context, uint32_t master_clock, uint32_t clock_div, uint32_t options)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 memset(context, 0, sizeof(*context));
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 context->clock_inc = clock_div * 8;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 context->audio = render_audio_source("YMF262", master_clock, context->clock_inc * OPL3_NUM_OPERATORS, 2);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 ymf262_reset(context);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 void ymf262_reset(ymf262_context *context)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 //TODO: implement me
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 void ymf262_free(ymf262_context *context)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 render_free_source(context->audio);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 free(context);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 void ymf262_adjust_master_clock(ymf262_context *context, uint32_t master_clock)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * OPL3_NUM_OPERATORS);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 void ymf262_adjust_cycles(ymf262_context *context, uint32_t deduction)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 context->cycle -= deduction;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 void ymf262_run(ymf262_context *context, uint32_t to_cycle)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 for (; context->cycle < to_cycle; context->cycle += context->clock_inc)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 context->current_op++;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 if (context->current_op == OPL3_NUM_OPERATORS) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 context->current_op = 0;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 int16_t left = 0, right = 0;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 render_put_stereo_sample(context->audio, left, right);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 void ymf262_address_write_part1(ymf262_context *context, uint8_t address)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 context->selected_reg = address;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 context->selected_part = 0;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 void ymf262_address_write_part2(ymf262_context *context, uint8_t address)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 context->selected_reg = address;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 context->selected_part = 0;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
59 static void ymf262_update_connections(ymf262_context *context, uint8_t channel, uint8_t csel_bit)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
60 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
61 uint8_t channel_off = channel >= 9 ? channel - 9 : channel;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
62 uint8_t op = channel_off;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
63 if (op > 5) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
64 op += 6;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
65 } else if (op > 2) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
66 op += 3;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
67 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
68 if (channel >= 9) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
69 op += 18;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
70 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
71 if (context->opl3_mode && channel_off < 6 && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
72 if (channel_off > 2) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
73 channel -= 3;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
74 op -= 6;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
75 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
76 uint8_t alg = (context->channels[channel].algorithm & 1) << 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
77 alg |= context->channels[channel + 3].algorithm & 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
78 switch (alg)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
79 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
80 case 0:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
81 context->operators[op + 3].mod_src[0] = &context->operators[op].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
82 context->operators[op + 6].mod_src[0] = &context->operators[op + 3].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
83 context->operators[op + 9].mod_src[0] = &context->operators[op + 6].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
84 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
85 case 1:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
86 context->operators[op + 3].mod_src[0] = &context->operators[op].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
87 context->operators[op + 6].mod_src[0] = NULL;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
88 context->operators[op + 9].mod_src[0] = &context->operators[op + 6].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
89 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
90 case 2:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
91 context->operators[op + 3].mod_src[0] = NULL;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
92 context->operators[op + 6].mod_src[0] = &context->operators[op + 3].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
93 context->operators[op + 9].mod_src[0] = &context->operators[op + 6].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
94 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
95 case 3:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
96 context->operators[op + 3].mod_src[0] = NULL;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
97 context->operators[op + 6].mod_src[0] = &context->operators[op + 3].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
98 context->operators[op + 9].mod_src[0] = NULL;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
99 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
100 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
101 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
102 context->operators[op].mod_src[0] = NULL;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
103 context->operators[op + 3].mod_src[0] = context->channels[channel].algorithm ? NULL : &context->operators[op].output;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
104 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
105 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
106
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
107 void ymf262_calc_phase_inc(ymf262_context *context, ym_channel *channel, ym_operator *operator)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
108 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
109 int32_t inc = channel->fnum;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
110 //TODO: vibrato?
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
111 if (!channel->block) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
112 inc >>= 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
113 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
114 inc <<= (channel->block-1);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
115 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
116 if (operator->multiple) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
117 inc *= operator->multiple;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
118 inc &= 0xFFFFF;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
119 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
120 //0.5
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
121 inc >>= 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
122 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
123 operator->phase_inc = inc;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
124 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
125
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 #define OPL3_NTS 0x08
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 void ymf262_data_write(ymf262_context *context, uint8_t value)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 if (!context->selected_reg) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 return;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 uint8_t old = 0;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 if (context->selected_reg >= OPL3_PARAM_START && context->selected_reg < OPL3_PARAM_END) {
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
135 uint8_t channel, op;
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 if (context->selected_part) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137 old = context->part2_regs[context->selected_reg - OPL3_PARAM_START];
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 context->part2_regs[context->selected_reg - OPL3_PARAM_START] = value;
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
139 channel = 9;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
140 op = 18;
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 } else {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 old = context->part1_regs[context->selected_reg - OPL3_PARAM_START];
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 context->part1_regs[context->selected_reg - OPL3_PARAM_START] = value;
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
144 channel = 0;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
145 op = 0;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
146 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
147 if (context->selected_reg < 0xA0 || context->selected_reg >= 0xE0) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
148 uint8_t op_off = context->selected_reg & 0x1F;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
149 if ((op_off >= 0x26 && op_off < 0x28) || (op_off >= 0x2E && op_off < 0x30) || op_off > 0x35) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
150 return;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
151 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
152 if (op_off >= 0x30) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
153 op_off -= 4;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
154 } else if (op_off >= 0x28) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
155 op_off -= 2;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
156 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
157 op += op_off;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
158 ym_operator *operator = context->operators + op;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
159 switch (context->selected_reg & 0xE0)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
160 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
161 case 0x20:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
162 operator->multiple = value & 0xF;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
163 operator->rates[PHASE_SUSTAIN] = (value & 0x20) ? 0 : operator->rates[PHASE_RELEASE];
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
164 operator->am = value & 0x80;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
165 //TODO: KSR,VIB
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
166 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
167 case 0x40:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
168 operator->total_level = (value & 0x3F) << 6;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
169 //TODO: KSL
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
170 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
171 case 0x60:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
172 //TODO: what should the LSB be?
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
173 operator->rates[PHASE_ATTACK] = (value & 0xF0) >> 3 | 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
174 operator->rates[PHASE_DECAY] = (value & 0xF) << 1 | 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
175 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
176 case 0x80:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
177 operator->rates[PHASE_RELEASE] = (value & 0xF) << 1 | 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
178 operator->sustain_level = (value & 0xF0) << 3;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
179 if (operator->sustain_level == 0x780) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
180 operator->sustain_level = MAX_ENVELOPE;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
181 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
182 if (!((context->selected_part ? context->part2_regs : context->part1_regs)[context->selected_reg - 0x60] & 0x20)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
183 operator->rates[PHASE_SUSTAIN] = operator->rates[PHASE_RELEASE];
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
184 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
185 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
186 case 0xE0:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
187 operator->wave = value & (context->opl3_mode ? 0x7 : 0x3);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
188 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
189 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
190 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
191 uint8_t channel_off = context->selected_reg & 0xF;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
192 if (channel_off > 8 && context->selected_reg != 0xBD) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
193 return;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
194 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
195 uint8_t csel_bit = channel_off > 2 ? channel_off - 3 : channel_off;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
196 if (channel) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
197 csel_bit += 3;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
198 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
199 csel_bit = 1 << csel_bit;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
200 if (context->selected_reg < 0xC0 && context->opl3_mode && (channel_off > 2 && channel_off < 6) && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
201 //ignore writes to "upper" channel in 4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
202 return;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
203 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
204 channel += channel_off;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
205 op = channel_off;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
206 if (op > 5) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
207 op += 6;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
208 } else if (op > 2) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
209 op += 3;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
210 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
211 ym_channel *chan = context->channels + channel;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
212 switch(context->selected_reg & 0xF0)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
213 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
214 case 0xA0:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
215 chan->fnum &= ~0xFF;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
216 chan->fnum |= value;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
217 ymf262_calc_phase_inc(context, chan, context->operators + op);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
218 ymf262_calc_phase_inc(context, chan, context->operators + op + 3);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
219 if (context->opl3_mode && channel_off < 6 && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
220 //4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
221 ymf262_calc_phase_inc(context, chan, context->operators + op + 6);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
222 ymf262_calc_phase_inc(context, chan, context->operators + op + 9);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
223 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
224 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
225 case 0xB0:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
226 chan->fnum &= 0xFF;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
227 chan->fnum |= (value & 0x3) << 8;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
228 chan->block = (value >> 2) & 7;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
229 ymf262_calc_phase_inc(context, chan, context->operators + op);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
230 ymf262_calc_phase_inc(context, chan, context->operators + op + 3);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
231 if (context->opl3_mode && channel_off < 6 && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
232 //4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
233 ymf262_calc_phase_inc(context, chan, context->operators + op + 6);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
234 ymf262_calc_phase_inc(context, chan, context->operators + op + 9);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
235 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
236 if ((value ^ old) & 0x20) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
237 if (value & 0x20) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
238 keyon(context->operators + op, chan);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
239 keyon(context->operators + op + 3, chan);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
240 if (context->opl3_mode && channel_off < 6 && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
241 //4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
242 keyon(context->operators + op + 6, chan);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
243 keyon(context->operators + op + 9, chan);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
244 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
245 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
246 keyoff(context->operators + op);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
247 keyoff(context->operators + op + 3);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
248 if (context->opl3_mode && channel_off < 6 && (context->connection_sel & csel_bit)) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
249 //4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
250 keyoff(context->operators + op + 6);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
251 keyoff(context->operators + op + 9);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
252 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
253 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
254 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
255 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
256 case 0xC0:
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
257 chan->algorithm = value & 1;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
258 chan->feedback = value >> 1 & 0x7;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
259 chan->lr = value & 0xF0;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
260 ymf262_update_connections(context, channel, csel_bit);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
261 break;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
262 }
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
264 } else if (context->selected_part) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 if (context->selected_reg <= sizeof(context->timer_test)) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 old = context->timer_test[context->selected_reg - 1];
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
267 context->timer_test[context->selected_reg - 1] = value;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268 } else if (context->selected_reg == OPL3_NTS) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 old = context->nts;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
270 context->nts = value;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 } else {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 return;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
273 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
274 } else {
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
275
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
276 switch (context->selected_reg)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
278 case 0x01:
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
279 old = context->part2_test;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
280 context->part2_test = value;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
281 break;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
282 case 0x04:
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
283 old = context->connection_sel;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
284 context->connection_sel = value;
2565
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
285 if (context->opl3_mode) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
286 uint8_t changes = old ^ value;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
287 for (uint8_t i = 0; i < 6; i++)
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
288 {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
289 uint8_t csel_bit = 1 << i;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
290 if (changes & csel_bit) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
291 uint8_t channel = i > 2 ? i + 9 : i;
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
292 if (value & csel_bit) {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
293 //switched to 4-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
294 ymf262_update_connections(context, channel, csel_bit);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
295 } else {
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
296 //switched to 2-op mode
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
297 ymf262_update_connections(context, channel, csel_bit);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
298 ymf262_update_connections(context, channel + 3, csel_bit);
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
299 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
300 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
301 }
eb588f22ec76 More work on OPL3 emulation
Michael Pavone <pavone@retrodev.com>
parents: 2558
diff changeset
302 }
2558
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
303 break;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
304 case 0x05:
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
305 old = context->opl3_mode;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
306 context->opl3_mode = value;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
307 break;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
308 default:
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
309 return;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
310 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
311 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
312 if (value != old) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
313 if (context->vgm) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
314 if (context->selected_reg) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
315 vgm_ymf262_part2_write(context->vgm, context->cycle, context->selected_reg, value);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
316 } else {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
317 vgm_ymf262_part1_write(context->vgm, context->cycle, context->selected_reg, value);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
318 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
319 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
320 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
321 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
322
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
323 void ymf262_vgm_log(ymf262_context *context, uint32_t master_clock, vgm_writer *vgm)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
324 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
325 vgm_ymf262_init(vgm, 8 * master_clock / context->clock_inc);
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
326 context->vgm = vgm;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
327 //TODO: write initial state
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
328 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
329
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
330 uint8_t ymf262_read_status(ymf262_context *context, uint32_t cycle, uint32_t port)
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
331 {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
332 if (port) {
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
333 //TODO: Investigate behavior of invalid status reads
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
334 return 0xFF;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
335 }
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
336 return context->status;
3f58fec775df Initial work on YMF262 (aka OPL3) emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
337 }