1 /* gameplaySP
2 *
3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21 #include "common.h"
22 u32 global_enable_audio = 1;
23
24 direct_sound_struct direct_sound_channel[2];
25 gbc_sound_struct gbc_sound_channel[4];
26
27 u32 sound_frequency = GBA_SOUND_FREQUENCY;
28
29 u32 sound_on;
30 static s16 sound_buffer[BUFFER_SIZE];
31 static u32 sound_buffer_base;
32
33 static u32 sound_last_cpu_ticks;
34 static fixed16_16 gbc_sound_tick_step;
35
36 /* Queue 1 sample to the top of the DS FIFO, wrap around circularly */
37
sound_timer_queue8(u32 channel,u8 value)38 void sound_timer_queue8(u32 channel, u8 value)
39 {
40 direct_sound_struct *ds = direct_sound_channel + channel;
41
42 *((s8 *)(ds->fifo + ds->fifo_top)) = value;
43 ds->fifo_top = (ds->fifo_top + 1) % 32;
44 }
45
46 /* Queue 2 samples to the top of the DS FIFO, wrap around circularly */
47
sound_timer_queue16(u32 channel,u16 value)48 void sound_timer_queue16(u32 channel, u16 value)
49 {
50 direct_sound_struct *ds = direct_sound_channel + channel;
51
52 *((s8 *)(ds->fifo + ds->fifo_top)) = value & 0xFF;
53 ds->fifo_top = (ds->fifo_top + 1) % 32;
54
55 *((s8 *)(ds->fifo + ds->fifo_top)) = value >> 8;
56 ds->fifo_top = (ds->fifo_top + 1) % 32;
57 }
58
59 /* Queue 4 samples to the top of the DS FIFO, wrap around circularly */
60
sound_timer_queue32(u32 channel,u32 value)61 void sound_timer_queue32(u32 channel, u32 value)
62 {
63 direct_sound_struct *ds = direct_sound_channel + channel;
64
65 *((s8 *)(ds->fifo + ds->fifo_top)) = value & 0xFF;
66 ds->fifo_top = (ds->fifo_top + 1) % 32;
67
68 *((s8 *)(ds->fifo + ds->fifo_top)) = (value >> 8) & 0xFF;
69 ds->fifo_top = (ds->fifo_top + 1) % 32;
70
71 *((s8 *)(ds->fifo + ds->fifo_top)) = (value >> 16) & 0xFF;
72 ds->fifo_top = (ds->fifo_top + 1) % 32;
73
74 *((s8 *)(ds->fifo + ds->fifo_top)) = (value >> 24);
75 ds->fifo_top = (ds->fifo_top + 1) % 32;
76 }
77
78
sound_timer(fixed8_24 frequency_step,u32 channel)79 void sound_timer(fixed8_24 frequency_step, u32 channel)
80 {
81 unsigned sample_status = DIRECT_SOUND_INACTIVE;
82 direct_sound_struct *ds = direct_sound_channel + channel;
83
84 fixed8_24 fifo_fractional = ds->fifo_fractional;
85 u32 buffer_index = ds->buffer_index;
86 s16 current_sample, next_sample;
87
88 current_sample = ds->fifo[ds->fifo_base] << 4;
89 ds->fifo_base = (ds->fifo_base + 1) % 32;
90 next_sample = ds->fifo[ds->fifo_base] << 4;
91
92 if(sound_on == 1)
93 {
94 if(ds->volume == DIRECT_SOUND_VOLUME_50)
95 {
96 current_sample >>= 1;
97 next_sample >>= 1;
98 }
99
100 sample_status = ds->status;
101
102 }
103
104 // Unqueue 1 sample from the base of the DS FIFO and place it on the audio
105 // buffer for as many samples as necessary. If the DS FIFO is 16 bytes or
106 // smaller and if DMA is enabled for the sound channel initiate a DMA transfer
107 // to the DS FIFO.
108
109 switch(sample_status)
110 {
111 case DIRECT_SOUND_INACTIVE:
112 /* render samples NULL */
113 while(fifo_fractional <= 0xFFFFFF)
114 {
115 fifo_fractional += frequency_step;
116 buffer_index = (buffer_index + 2) % BUFFER_SIZE;
117 }
118 break;
119
120 case DIRECT_SOUND_RIGHT:
121 /* render samples RIGHT */
122 while(fifo_fractional <= 0xFFFFFF)
123 {
124 s16 dest_sample = current_sample +
125 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8));
126
127 sound_buffer[buffer_index + 1] += dest_sample;
128
129 fifo_fractional += frequency_step;
130 buffer_index = (buffer_index + 2) % BUFFER_SIZE;
131 }
132 break;
133
134 case DIRECT_SOUND_LEFT:
135 /* render samples LEFT */
136 while(fifo_fractional <= 0xFFFFFF)
137 {
138 s16 dest_sample = current_sample +
139 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8));
140
141 sound_buffer[buffer_index] += dest_sample;
142
143 fifo_fractional += frequency_step;
144 buffer_index = (buffer_index + 2) % BUFFER_SIZE;
145 }
146 break;
147
148 case DIRECT_SOUND_LEFTRIGHT:
149 /* render samples LEFT and RIGHT. */
150 while(fifo_fractional <= 0xFFFFFF)
151 {
152 s16 dest_sample = current_sample +
153 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8));
154
155 sound_buffer[buffer_index] += dest_sample;
156 sound_buffer[buffer_index + 1] += dest_sample;
157 fifo_fractional += frequency_step;
158 buffer_index = (buffer_index + 2) % BUFFER_SIZE;
159 }
160 break;
161 }
162
163 ds->buffer_index = buffer_index;
164 ds->fifo_fractional = fp8_24_fractional_part(fifo_fractional);
165
166 if(((ds->fifo_top - ds->fifo_base) % 32) <= 16)
167 {
168 if(dma[1].direct_sound_channel == channel)
169 dma_transfer(dma + 1);
170
171 if(dma[2].direct_sound_channel == channel)
172 dma_transfer(dma + 2);
173 }
174 }
175
sound_reset_fifo(u32 channel)176 void sound_reset_fifo(u32 channel)
177 {
178 direct_sound_struct *ds = direct_sound_channel;
179
180 memset(ds->fifo, 0, 32);
181 }
182
183 // Initial pattern data = 4bits (signed)
184 // Channel volume = 12bits
185 // Envelope volume = 14bits
186 // Master volume = 2bits
187
188 // Recalculate left and right volume as volume changes.
189 // To calculate the current sample, use (sample * volume) >> 16
190
191 // Square waves range from -8 (low) to 7 (high)
192
193 s8 square_pattern_duty[4][8] =
194 {
195 { 0xF8, 0xF8, 0xF8, 0xF8, 0x07, 0xF8, 0xF8, 0xF8 },
196 { 0xF8, 0xF8, 0xF8, 0xF8, 0x07, 0x07, 0xF8, 0xF8 },
197 { 0xF8, 0xF8, 0x07, 0x07, 0x07, 0x07, 0xF8, 0xF8 },
198 { 0x07, 0x07, 0x07, 0x07, 0xF8, 0xF8, 0x07, 0x07 },
199 };
200
201 s8 wave_samples[64];
202
203 u32 noise_table15[1024];
204 u32 noise_table7[4];
205
206 u32 gbc_sound_master_volume_table[4] = { 1, 2, 4, 0 };
207
208 u32 gbc_sound_channel_volume_table[8] =
209 {
210 fixed_div(0, 7, 12),
211 fixed_div(1, 7, 12),
212 fixed_div(2, 7, 12),
213 fixed_div(3, 7, 12),
214 fixed_div(4, 7, 12),
215 fixed_div(5, 7, 12),
216 fixed_div(6, 7, 12),
217 fixed_div(7, 7, 12)
218 };
219
220 u32 gbc_sound_envelope_volume_table[16] =
221 {
222 fixed_div(0, 15, 14),
223 fixed_div(1, 15, 14),
224 fixed_div(2, 15, 14),
225 fixed_div(3, 15, 14),
226 fixed_div(4, 15, 14),
227 fixed_div(5, 15, 14),
228 fixed_div(6, 15, 14),
229 fixed_div(7, 15, 14),
230 fixed_div(8, 15, 14),
231 fixed_div(9, 15, 14),
232 fixed_div(10, 15, 14),
233 fixed_div(11, 15, 14),
234 fixed_div(12, 15, 14),
235 fixed_div(13, 15, 14),
236 fixed_div(14, 15, 14),
237 fixed_div(15, 15, 14)
238 };
239
240 u32 gbc_sound_buffer_index = 0;
241 u32 gbc_sound_last_cpu_ticks = 0;
242 u32 gbc_sound_partial_ticks = 0;
243
244 u32 gbc_sound_master_volume_left;
245 u32 gbc_sound_master_volume_right;
246 u32 gbc_sound_master_volume;
247
248 #define update_volume_channel_envelope(channel) \
249 volume_##channel = gbc_sound_envelope_volume_table[envelope_volume] * \
250 gbc_sound_channel_volume_table[gbc_sound_master_volume_##channel] * \
251 gbc_sound_master_volume_table[gbc_sound_master_volume] \
252
253 #define update_volume_channel_noenvelope(channel) \
254 volume_##channel = gs->wave_volume * \
255 gbc_sound_channel_volume_table[gbc_sound_master_volume_##channel] * \
256 gbc_sound_master_volume_table[gbc_sound_master_volume] \
257
258 #define update_volume(type) \
259 update_volume_channel_##type(left); \
260 update_volume_channel_##type(right) \
261
262 #define update_tone_sweep() \
263 if(gs->sweep_status) \
264 { \
265 u32 sweep_ticks = gs->sweep_ticks - 1; \
266 \
267 if(sweep_ticks == 0) \
268 { \
269 u32 rate = gs->rate; \
270 \
271 if(gs->sweep_direction) \
272 rate = rate - (rate >> gs->sweep_shift); \
273 else \
274 rate = rate + (rate >> gs->sweep_shift); \
275 \
276 if(rate > 2048) \
277 rate = 2048; \
278 \
279 frequency_step = float_to_fp16_16(((131072.0f / (2048 - rate)) * 8.0f) \
280 / sound_frequency); \
281 \
282 gs->frequency_step = frequency_step; \
283 gs->rate = rate; \
284 \
285 sweep_ticks = gs->sweep_initial_ticks; \
286 } \
287 gs->sweep_ticks = sweep_ticks; \
288 } \
289
290 #define update_tone_nosweep() \
291
292 #define update_tone_envelope() \
293 if(gs->envelope_status) \
294 { \
295 u32 envelope_ticks = gs->envelope_ticks - 1; \
296 envelope_volume = gs->envelope_volume; \
297 \
298 if(envelope_ticks == 0) \
299 { \
300 if(gs->envelope_direction) \
301 { \
302 if(envelope_volume != 15) \
303 envelope_volume = gs->envelope_volume + 1; \
304 } \
305 else \
306 { \
307 if(envelope_volume != 0) \
308 envelope_volume = gs->envelope_volume - 1; \
309 } \
310 \
311 update_volume(envelope); \
312 \
313 gs->envelope_volume = envelope_volume; \
314 gs->envelope_ticks = gs->envelope_initial_ticks; \
315 } \
316 else \
317 gs->envelope_ticks = envelope_ticks; \
318 } \
319
320 #define update_tone_noenvelope() \
321
322 #define update_tone_counters(envelope_op, sweep_op) \
323 tick_counter += gbc_sound_tick_step; \
324 if(tick_counter > 0xFFFF) \
325 { \
326 if(gs->length_status) \
327 { \
328 u32 length_ticks = gs->length_ticks - 1; \
329 gs->length_ticks = length_ticks; \
330 \
331 if(length_ticks == 0) \
332 { \
333 gs->active_flag = 0; \
334 break; \
335 } \
336 } \
337 \
338 update_tone_##envelope_op(); \
339 update_tone_##sweep_op(); \
340 \
341 tick_counter &= 0xFFFF; \
342 } \
343
344 #define gbc_sound_render_sample_right() \
345 sound_buffer[buffer_index + 1] += (current_sample * volume_right) >> 22 \
346
347 #define gbc_sound_render_sample_left() \
348 sound_buffer[buffer_index] += (current_sample * volume_left) >> 22 \
349
350 #define gbc_sound_render_sample_both() \
351 gbc_sound_render_sample_right(); \
352 gbc_sound_render_sample_left() \
353
354 #define gbc_sound_render_samples(type, sample_length, envelope_op, sweep_op) \
355 for(i = 0; i < buffer_ticks; i++) \
356 { \
357 current_sample = \
358 sample_data[fp16_16_to_u32(sample_index) % sample_length]; \
359 gbc_sound_render_sample_##type(); \
360 \
361 sample_index += frequency_step; \
362 buffer_index = (buffer_index + 2) % BUFFER_SIZE; \
363 \
364 update_tone_counters(envelope_op, sweep_op); \
365 } \
366
367 #define gbc_noise_wrap_full 32767
368
369 #define gbc_noise_wrap_half 126
370
371 #define get_noise_sample_full() \
372 current_sample = \
373 ((s32)(noise_table15[fp16_16_to_u32(sample_index) >> 5] << \
374 (fp16_16_to_u32(sample_index) & 0x1F)) >> 31) & 0x0F \
375
376 #define get_noise_sample_half() \
377 current_sample = \
378 ((s32)(noise_table7[fp16_16_to_u32(sample_index) >> 5] << \
379 (fp16_16_to_u32(sample_index) & 0x1F)) >> 31) & 0x0F \
380
381 #define gbc_sound_render_noise(type, noise_type, envelope_op, sweep_op) \
382 for(i = 0; i < buffer_ticks; i++) \
383 { \
384 get_noise_sample_##noise_type(); \
385 gbc_sound_render_sample_##type(); \
386 \
387 sample_index += frequency_step; \
388 \
389 if(sample_index >= u32_to_fp16_16(gbc_noise_wrap_##noise_type)) \
390 sample_index -= u32_to_fp16_16(gbc_noise_wrap_##noise_type); \
391 \
392 buffer_index = (buffer_index + 2) % BUFFER_SIZE; \
393 update_tone_counters(envelope_op, sweep_op); \
394 } \
395
396 #define gbc_sound_render_channel(type, sample_length, envelope_op, sweep_op) \
397 buffer_index = gbc_sound_buffer_index; \
398 sample_index = gs->sample_index; \
399 frequency_step = gs->frequency_step; \
400 tick_counter = gs->tick_counter; \
401 \
402 update_volume(envelope_op); \
403 \
404 switch(gs->status) \
405 { \
406 case GBC_SOUND_INACTIVE: \
407 break; \
408 \
409 case GBC_SOUND_LEFT: \
410 gbc_sound_render_##type(left, sample_length, envelope_op, sweep_op); \
411 break; \
412 \
413 case GBC_SOUND_RIGHT: \
414 gbc_sound_render_##type(right, sample_length, envelope_op, sweep_op); \
415 break; \
416 \
417 case GBC_SOUND_LEFTRIGHT: \
418 gbc_sound_render_##type(both, sample_length, envelope_op, sweep_op); \
419 break; \
420 } \
421 \
422 gs->sample_index = sample_index; \
423 gs->tick_counter = tick_counter; \
424
update_gbc_sound(u32 cpu_ticks)425 void update_gbc_sound(u32 cpu_ticks)
426 {
427 fixed16_16 buffer_ticks = float_to_fp16_16((float)(cpu_ticks -
428 gbc_sound_last_cpu_ticks) * sound_frequency / GBC_BASE_RATE);
429 u32 i, i2;
430 gbc_sound_struct *gs = gbc_sound_channel;
431 fixed16_16 sample_index, frequency_step;
432 fixed16_16 tick_counter;
433 u32 buffer_index;
434 s32 volume_left, volume_right;
435 u32 envelope_volume;
436 s32 current_sample;
437 u32 sound_status = address16(io_registers, 0x84) & 0xFFF0;
438 s8 *sample_data;
439 s8 *wave_bank;
440 u8 *wave_ram = ((u8 *)io_registers) + 0x90;
441
442 gbc_sound_partial_ticks += fp16_16_fractional_part(buffer_ticks);
443 buffer_ticks = fp16_16_to_u32(buffer_ticks);
444
445 if(gbc_sound_partial_ticks > 0xFFFF)
446 {
447 buffer_ticks += 1;
448 gbc_sound_partial_ticks &= 0xFFFF;
449 }
450
451 if(sound_on == 1)
452 {
453 gs = gbc_sound_channel + 0;
454 if(gs->active_flag)
455 {
456 sound_status |= 0x01;
457 sample_data = gs->sample_data;
458 envelope_volume = gs->envelope_volume;
459 gbc_sound_render_channel(samples, 8, envelope, sweep);
460 }
461
462 gs = gbc_sound_channel + 1;
463 if(gs->active_flag)
464 {
465 sound_status |= 0x02;
466 sample_data = gs->sample_data;
467 envelope_volume = gs->envelope_volume;
468 gbc_sound_render_channel(samples, 8, envelope, nosweep);
469 }
470
471 gs = gbc_sound_channel + 2;
472 if(gbc_sound_wave_update)
473 {
474 unsigned bank = (gs->wave_bank == 1) ? 1 : 0;
475
476 wave_bank = wave_samples + (bank * 32);
477 for(i = 0, i2 = 0; i < 16; i++, i2 += 2)
478 {
479 current_sample = wave_ram[i];
480 wave_bank[i2] = (((current_sample >> 4) & 0x0F) - 8);
481 wave_bank[i2 + 1] = ((current_sample & 0x0F) - 8);
482 }
483
484 gbc_sound_wave_update = 0;
485 }
486
487 if((gs->active_flag) && (gs->master_enable))
488 {
489 sound_status |= 0x04;
490 sample_data = wave_samples;
491 if(gs->wave_type == 0)
492 {
493 if(gs->wave_bank == 1)
494 sample_data += 32;
495
496 gbc_sound_render_channel(samples, 32, noenvelope, nosweep);
497 }
498 else
499 {
500 gbc_sound_render_channel(samples, 64, noenvelope, nosweep);
501 }
502 }
503
504 gs = gbc_sound_channel + 3;
505 if(gs->active_flag)
506 {
507 sound_status |= 0x08;
508 envelope_volume = gs->envelope_volume;
509
510 if(gs->noise_type == 1)
511 {
512 gbc_sound_render_channel(noise, half, envelope, nosweep);
513 }
514 else
515 {
516 gbc_sound_render_channel(noise, full, envelope, nosweep);
517 }
518 }
519 }
520
521 address16(io_registers, 0x84) = sound_status;
522
523 gbc_sound_last_cpu_ticks = cpu_ticks;
524 gbc_sound_buffer_index =
525 (gbc_sound_buffer_index + (buffer_ticks * 2)) % BUFFER_SIZE;
526 }
527
528 // Special thanks to blarrg for the LSFR frequency used in Meridian, as posted
529 // on the forum at http://meridian.overclocked.org:
530 // http://meridian.overclocked.org/cgi-bin/wwwthreads/showpost.pl?Board=merid
531 // angeneraldiscussion&Number=2069&page=0&view=expanded&mode=threaded&sb=4
532 // Hope you don't mind me borrowing it ^_-
533
init_noise_table(u32 * table,u32 period,u32 bit_length)534 static void init_noise_table(u32 *table, u32 period, u32 bit_length)
535 {
536 u32 shift_register = 0xFF;
537 u32 mask = ~(1 << bit_length);
538 s32 table_pos, bit_pos;
539 u32 current_entry;
540 u32 table_period = (period + 31) / 32;
541
542 // Bits are stored in reverse order so they can be more easily moved to
543 // bit 31, for sign extended shift down.
544
545 for(table_pos = 0; table_pos < table_period; table_pos++)
546 {
547 current_entry = 0;
548 for(bit_pos = 31; bit_pos >= 0; bit_pos--)
549 {
550 current_entry |= (shift_register & 0x01) << bit_pos;
551
552 shift_register =
553 ((1 & (shift_register ^ (shift_register >> 1))) << bit_length) |
554 ((shift_register >> 1) & mask);
555 }
556
557 table[table_pos] = current_entry;
558 }
559 }
560
reset_sound(void)561 void reset_sound(void)
562 {
563 direct_sound_struct *ds = direct_sound_channel;
564 gbc_sound_struct *gs = gbc_sound_channel;
565 u32 i;
566
567 sound_on = 0;
568 sound_buffer_base = 0;
569 sound_last_cpu_ticks = 0;
570 memset(sound_buffer, 0, sizeof(sound_buffer));
571
572 for(i = 0; i < 2; i++, ds++)
573 {
574 ds->buffer_index = 0;
575 ds->status = DIRECT_SOUND_INACTIVE;
576 ds->fifo_top = 0;
577 ds->fifo_base = 0;
578 ds->fifo_fractional = 0;
579 ds->last_cpu_ticks = 0;
580 memset(ds->fifo, 0, 32);
581 }
582
583 gbc_sound_buffer_index = 0;
584 gbc_sound_last_cpu_ticks = 0;
585 gbc_sound_partial_ticks = 0;
586
587 gbc_sound_master_volume_left = 0;
588 gbc_sound_master_volume_right = 0;
589 gbc_sound_master_volume = 0;
590 memset(wave_samples, 0, 64);
591
592 for(i = 0; i < 4; i++, gs++)
593 {
594 gs->status = GBC_SOUND_INACTIVE;
595 gs->sample_data = square_pattern_duty[2];
596 gs->active_flag = 0;
597 }
598 }
599
init_sound(int need_reset)600 void init_sound(int need_reset)
601 {
602 gbc_sound_tick_step =
603 float_to_fp16_16(256.0f / sound_frequency);
604
605 init_noise_table(noise_table15, 32767, 14);
606 init_noise_table(noise_table7, 127, 6);
607
608 if (need_reset)
609 reset_sound();
610 }
611
612 #define sound_savestate_builder(type) \
613 void sound_##type##_savestate(void) \
614 { \
615 state_mem_##type##_variable(sound_on); \
616 state_mem_##type##_variable(sound_buffer_base); \
617 state_mem_##type##_variable(sound_last_cpu_ticks); \
618 state_mem_##type##_variable(gbc_sound_buffer_index); \
619 state_mem_##type##_variable(gbc_sound_last_cpu_ticks); \
620 state_mem_##type##_variable(gbc_sound_partial_ticks); \
621 state_mem_##type##_variable(gbc_sound_master_volume_left); \
622 state_mem_##type##_variable(gbc_sound_master_volume_right); \
623 state_mem_##type##_variable(gbc_sound_master_volume); \
624 state_mem_##type##_array(wave_samples); \
625 state_mem_##type##_array(direct_sound_channel); \
626 state_mem_##type##_array(gbc_sound_channel); \
627 }
628
629 sound_savestate_builder(read)
630 sound_savestate_builder(write)
631
632
633 #include "libretro.h"
634
635 static retro_audio_sample_batch_t audio_batch_cb;
retro_set_audio_sample(retro_audio_sample_t cb)636 void retro_set_audio_sample(retro_audio_sample_t cb) { }
retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)637 void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }
638
render_audio(void)639 void render_audio(void)
640 {
641 static s16 stream_base[512];
642 s16 *source;
643 u32 i;
644
645 while (((gbc_sound_buffer_index - sound_buffer_base) & BUFFER_SIZE_MASK) > 512)
646 {
647 source = (s16 *)(sound_buffer + sound_buffer_base);
648 for(i = 0; i < 512; i++)
649 {
650 s32 current_sample = source[i];
651 if(current_sample > 2047)
652 current_sample = 2047;
653 if(current_sample < -2048)
654 current_sample = -2048;
655 stream_base[i] = current_sample << 4;
656 source[i] = 0;
657 }
658 audio_batch_cb(stream_base, 256);
659 sound_buffer_base += 512;
660 sound_buffer_base &= BUFFER_SIZE_MASK;
661 }
662 }
663