3 * Adlib OPL2/OPL3 FM synthesizer chipset controller library.
4 * (C) 2010-2012 Jonathan Campbell.
5 * Hackipedia DOS library.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
10 * Compiles for intended target environments:
11 * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box] */
13 //#include "src/lib/doslib/cpu.h"
14 #include "src/lib/doslib/8254.h" /* 8254 timer */
17 #define ADLIB_FM_VOICES 18
19 #define ADLIB_IO_INDEX 0x388
20 #define ADLIB_IO_STATUS 0x388
21 #define ADLIB_IO_DATA 0x389
23 #define ADLIB_IO_INDEX2 0x38A
24 #define ADLIB_IO_STATUS2 0x38A
25 #define ADLIB_IO_DATA2 0x38B
28 #define ADLIB_STATUS_TIMERS_EXPIRED 0x80
29 #define ADLIB_STATUS_TIMER1_EXPIRED 0x40
30 #define ADLIB_STATUS_TIMER2_EXPIRED 0x20
33 ADLIB_FM_DUAL_OPL2=0x01,
37 struct adlib_fm_operator {
39 uint8_t am:1; /* bit 7: Apply amplitude modulation */
40 uint8_t vibrato:1; /* bit 6: Apply vibrato */
41 uint8_t sustain:1; /* bit 5: maintain sustain level */
42 uint8_t key_scaling_rate:1; /* bit 4: increase ADSR enevelope speed as pitch increases */
43 uint8_t mod_multiple:4; /* bits 0-3: modulator multiple (1=voice frequency, 2=one octave above) */
45 uint8_t level_key_scale:2; /* bits 7-6: decrease volume as frequency rises (0=none 1=1.5dB/8ve 2=3dB/8ve 3=6dB/8ve) */
46 uint8_t total_level:6; /* bits 5-0: total output level (for sanity's sake, we maintain here as 0=silent 0x3F=full even though hardware is opposite) */
48 uint8_t attack_rate:4; /* bits 7-4: attack rate */
49 uint8_t decay_rate:4; /* bits 3-0: decay rate */
51 uint8_t sustain_level:4; /* bits 7-4: sustain level */
52 uint8_t release_rate:4; /* bits 3-0: release rate */
54 uint16_t key_on:1; /* bit 5: voice the channel */
55 uint16_t octave:3; /* bits 4-2: octave */
56 uint16_t f_number:10; /* bits 1-0, then bits 7-0: F-number (frequency) */
58 uint8_t ch_a:1; /* bit 4: OPL3: Channel A output */
59 uint8_t ch_b:1; /* bit 5: OPL3: Channel B output */
60 uint8_t ch_c:1; /* bit 6: OPL3: Channel C output */
61 uint8_t ch_d:1; /* bit 7: OPL3: Channel D output */
62 uint8_t feedback:3; /* bits 3-1: feedback strength */
63 uint8_t connection:1; /* bit 0: connection (operator 1 and 2 independent if set) */
65 uint8_t waveform:3; /* bits 1-0: which waveform to use */
68 struct adlib_fm_channel {
69 struct adlib_fm_operator mod,car;
74 uint8_t vibrato_depth:1;
75 uint8_t rythm_enable:1;
76 uint8_t bass_drum_on:1;
77 uint8_t snare_drum_on:1;
84 void shutdown_adlib();
85 void shutdown_adlib_opl3();
86 int probe_adlib(unsigned char sec);
87 unsigned char adlib_read(unsigned short i);
88 void adlib_write(unsigned short i,unsigned char d);
89 void adlib_update_group20(unsigned int op,struct adlib_fm_operator *f);
90 void adlib_update_group40(unsigned int op,struct adlib_fm_operator *f);
91 void adlib_update_group60(unsigned int op,struct adlib_fm_operator *f);
92 void adlib_update_group80(unsigned int op,struct adlib_fm_operator *f);
93 void adlib_update_groupA0(unsigned int channel,struct adlib_fm_channel *ch);
94 void adlib_update_groupC0(unsigned int channel,struct adlib_fm_channel *ch);
95 void adlib_update_groupE0(unsigned int op,struct adlib_fm_operator *f);
96 void adlib_update_operator(unsigned int op,struct adlib_fm_operator *f);
97 void adlib_freq_to_fm_op(struct adlib_fm_operator *f,double freq);
98 double adlib_fm_op_to_freq(struct adlib_fm_operator *f);
99 void adlib_update_bd(struct adlib_reg_bd *b);
100 void adlib_apply_all();
102 extern unsigned short adlib_voice_to_op_opl2[9];
103 extern unsigned short adlib_voice_to_op_opl3[18];
104 extern unsigned short* adlib_voice_to_op;
106 extern struct adlib_reg_bd adlib_reg_bd;
107 extern struct adlib_fm_channel adlib_fm[ADLIB_FM_VOICES];
108 extern int adlib_fm_voices;
109 extern unsigned char adlib_flags;
111 extern struct adlib_fm_channel adlib_fm_preset_deep_bass_drum;
112 extern struct adlib_fm_channel adlib_fm_preset_violin_opl3;
113 extern struct adlib_fm_channel adlib_fm_preset_violin_opl2;
114 extern struct adlib_fm_channel adlib_fm_preset_harpsichord;
115 extern struct adlib_fm_channel adlib_fm_preset_small_drum;
116 extern struct adlib_fm_channel adlib_fm_preset_piano;
117 extern struct adlib_fm_channel adlib_fm_preset_horn;
119 /* NTS: I have a Creative CT1350B card where we really do have to wait at least
120 * 33us per I/O access, because the OPL2 chip on it really is that slow.
122 * Peior to this fix, the adlib code would often fail on a real CT1350B
123 * (unless run just after the Sound Blaster test program) and even if it
124 * did run, only about 1/3rd of the voices would work. Upping the delay
125 * to 40us for OPL3 and 100us for OPL2 resolved these issues. */
126 static inline void adlib_wait() {
127 t8254_wait(t8254_us2ticks((adlib_flags & ADLIB_FM_OPL3) ? 40 : 100));
130 static inline unsigned char adlib_status(unsigned char which) {
132 return inp(ADLIB_IO_STATUS+(which*2));
135 static inline unsigned char adlib_status_imm(unsigned char which) {
136 return inp(ADLIB_IO_STATUS+(which*2));