1 /*
2   header file for software emulation for FM sound generator
3 
4 */
5 #ifndef _H_FM_FM_
6 #define _H_FM_FM_
7 
8 /* compiler dependence */
9 #ifndef UINT8
10 typedef unsigned char	UINT8;   /* unsigned  8bit */
11 typedef unsigned short	UINT16;  /* unsigned 16bit */
12 typedef unsigned int	UINT32;  /* unsigned 32bit */
13 #endif
14 #ifndef INT8
15 typedef signed char		INT8;    /* signed  8bit   */
16 typedef signed short	INT16;   /* signed 16bit   */
17 typedef signed int		INT32;   /* signed 32bit   */
18 #endif
19 
20 #if 1
21 /* struct describing a single operator (SLOT) */
22 typedef struct
23 {
24 	INT32	*DT;		/* #0x00 detune          :dt_tab[DT] */
25 	UINT8	ar;		/* #0x04 attack rate  */
26 	UINT8	d1r;		/* #0x05 decay rate   */
27 	UINT8	d2r;		/* #0x06 sustain rate */
28 	UINT8	rr;		/* #0x07 release rate */
29 	UINT32	mul;		/* #0x08 multiple        :ML_TABLE[ML] */
30 
31 	/* Phase Generator */
32 	UINT32	phase;		/* #0x0c phase counter | need_save */
33 	UINT32	Incr;		/* #0x10 phase step */
34 
35 	UINT8	KSR;		/* #0x14 key scale rate  :3-KSR */
36 	UINT8	ksr;		/* #0x15 key scale rate  :kcode>>(3-KSR) */
37 
38 	UINT8	key;		/* #0x16 0=last key was KEY OFF, 1=KEY ON */
39 
40 	/* Envelope Generator */
41 	UINT8	state;		/* #0x17 phase type: EG_OFF=0, EG_REL, EG_SUS, EG_DEC, EG_ATT | need_save */
42 	UINT16	tl;		/* #0x18 total level: TL << 3 */
43 	INT16	volume;		/* #0x1a envelope counter | need_save */
44 	UINT32	sl;		/* #0x1c sustain level:sl_table[SL] */
45 
46 	/* asm relies on this order: */
47 	union {
48 		struct {
49 			UINT32 eg_pack_rr;  /* #0x20 1 (release state) */
50 			UINT32 eg_pack_d2r; /* #0x24 2 (sustain state) */
51 			UINT32 eg_pack_d1r; /* #0x28 3 (decay state) */
52 			UINT32 eg_pack_ar;  /* #0x2c 4 (attack state) */
53 		};
54 		UINT32 eg_pack[4];
55 	};
56 } FM_SLOT;
57 
58 
59 typedef struct
60 {
61 	FM_SLOT	SLOT[4];	/* four SLOTs (operators) */
62 
63 	UINT8	ALGO;		/* +00 algorithm */
64 	UINT8	FB;		/* feedback shift */
65 	UINT8	pad[2];
66 	INT32	op1_out;	/* op1 output for feedback */
67 
68 	INT32	mem_value;	/* +08 delayed sample (MEM) value */
69 
70 	INT32	pms;		/* channel PMS */
71 	UINT8	ams;		/* channel AMS */
72 
73 	UINT8	kcode;		/* +11 key code:                        */
74 	UINT8   fn_h;		/* freq latch           */
75 	UINT8	pad2;
76 	UINT32	fc;		/* fnum,blk:adjusted to sample rate */
77 	UINT32	block_fnum;	/* current blk/fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
78 
79 	/* LFO */
80 	UINT8	AMmasks;	/* AM enable flag */
81 	UINT8	pad3[3];
82 } FM_CH;
83 
84 typedef struct
85 {
86 	int		clock;		/* master clock  (Hz)   */
87 	int		rate;		/* sampling rate (Hz)   */
88 	double	freqbase;	/* 08 frequency base       */
89 	UINT8	address;	/* 10 address register | need_save     */
90 	UINT8	status;		/* 11 status flag | need_save          */
91 	UINT8	mode;		/* mode  CSM / 3SLOT    */
92 	UINT8	pad;
93 	int		TA;			/* timer a              */
94 	int		TAC;		/* timer a maxval       */
95 	int		TAT;		/* timer a ticker | need_save */
96 	UINT8	TB;			/* timer b              */
97 	UINT8	pad2[3];
98 	int		TBC;		/* timer b maxval       */
99 	int		TBT;		/* timer b ticker | need_save */
100 	/* local time tables */
101 	INT32	dt_tab[8][32];/* DeTune table       */
102 } FM_ST;
103 
104 /***********************************************************/
105 /* OPN unit                                                */
106 /***********************************************************/
107 
108 /* OPN 3slot struct */
109 typedef struct
110 {
111 	UINT32  fc[3];			/* fnum3,blk3: calculated */
112 	UINT8	fn_h;			/* freq3 latch */
113 	UINT8	kcode[3];		/* key code */
114 	UINT32	block_fnum[3];	/* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
115 } FM_3SLOT;
116 
117 /* OPN/A/B common state */
118 typedef struct
119 {
120 	FM_ST	ST;				/* general state */
121 	FM_3SLOT SL3;			/* 3 slot mode state */
122 	UINT32  pan;			/* fm channels output mask (bit 1 = enable) */
123 
124 	UINT32	eg_cnt;			/* global envelope generator counter | need_save */
125 	UINT32	eg_timer;		/* global envelope generator counter works at frequency = chipclock/64/3 | need_save */
126 	UINT32	eg_timer_add;		/* step of eg_timer */
127 
128 	/* LFO */
129 	UINT32	lfo_cnt;		/* need_save */
130 	UINT32	lfo_inc;
131 
132 	UINT32	lfo_freq[8];	/* LFO FREQ table */
133 } FM_OPN;
134 
135 /* here's the virtual YM2612 */
136 typedef struct
137 {
138 	UINT8		REGS[0x200];			/* registers (for save states)       */
139 	INT32		addr_A1;			/* address line A1 | need_save       */
140 
141 	FM_CH		CH[6];				/* channel state */
142 
143 	/* dac output (YM2612) */
144 	int		dacen;
145 	INT32		dacout;
146 
147 	FM_OPN		OPN;				/* OPN state            */
148 
149 	UINT32		slot_mask;			/* active slot mask (performance hack) */
150 } YM2612;
151 #endif
152 
153 #ifndef EXTERNAL_YM2612
154 extern YM2612 ym2612;
155 #endif
156 
157 void YM2612Init_(int baseclock, int rate);
158 void YM2612ResetChip_(void);
159 int  YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty);
160 
161 int  YM2612Write_(unsigned int a, unsigned int v);
162 //unsigned char YM2612Read_(void);
163 
164 int  YM2612PicoTick_(int n);
165 void YM2612PicoStateLoad_(void);
166 
167 void *YM2612GetRegs(void);
168 void YM2612PicoStateSave2(int tat, int tbt);
169 int  YM2612PicoStateLoad2(int *tat, int *tbt);
170 
171 #ifndef __GP2X__
172 #define YM2612Init          YM2612Init_
173 #define YM2612ResetChip     YM2612ResetChip_
174 #define YM2612UpdateOne     YM2612UpdateOne_
175 #define YM2612PicoStateLoad YM2612PicoStateLoad_
176 #else
177 /* GP2X specific */
178 #include "../../platform/gp2x/940ctl.h"
179 extern int PicoIn.opt;
180 #define YM2612Init(baseclock,rate) { \
181 	if (PicoIn.opt&0x200) YM2612Init_940(baseclock, rate); \
182 	else               YM2612Init_(baseclock, rate); \
183 }
184 #define YM2612ResetChip() { \
185 	if (PicoIn.opt&0x200) YM2612ResetChip_940(); \
186 	else               YM2612ResetChip_(); \
187 }
188 #define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) \
189 	(PicoIn.opt&0x200) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \
190 				YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
191 #define YM2612PicoStateLoad() { \
192 	if (PicoIn.opt&0x200) YM2612PicoStateLoad_940(); \
193 	else               YM2612PicoStateLoad_(); \
194 }
195 #endif /* __GP2X__ */
196 
197 
198 #endif /* _H_FM_FM_ */
199