Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
/***************************************************************************
2
 
3
    Philips SAA1099 Sound driver
4
 
5
    By Juergen Buchmueller and Manuel Abadia
6
 
7
    SAA1099 register layout:
8
    ========================
9
 
10
    offs | 7654 3210 | description
11
    -----+-----------+---------------------------
12
    0x00 | ---- xxxx | Amplitude channel 0 (left)
13
    0x00 | xxxx ---- | Amplitude channel 0 (right)
14
    0x01 | ---- xxxx | Amplitude channel 1 (left)
15
    0x01 | xxxx ---- | Amplitude channel 1 (right)
16
    0x02 | ---- xxxx | Amplitude channel 2 (left)
17
    0x02 | xxxx ---- | Amplitude channel 2 (right)
18
    0x03 | ---- xxxx | Amplitude channel 3 (left)
19
    0x03 | xxxx ---- | Amplitude channel 3 (right)
20
    0x04 | ---- xxxx | Amplitude channel 4 (left)
21
    0x04 | xxxx ---- | Amplitude channel 4 (right)
22
    0x05 | ---- xxxx | Amplitude channel 5 (left)
23
    0x05 | xxxx ---- | Amplitude channel 5 (right)
24
         |           |
25
    0x08 | xxxx xxxx | Frequency channel 0
26
    0x09 | xxxx xxxx | Frequency channel 1
27
    0x0a | xxxx xxxx | Frequency channel 2
28
    0x0b | xxxx xxxx | Frequency channel 3
29
    0x0c | xxxx xxxx | Frequency channel 4
30
    0x0d | xxxx xxxx | Frequency channel 5
31
         |           |
32
    0x10 | ---- -xxx | Channel 0 octave select
33
    0x10 | -xxx ---- | Channel 1 octave select
34
    0x11 | ---- -xxx | Channel 2 octave select
35
    0x11 | -xxx ---- | Channel 3 octave select
36
    0x12 | ---- -xxx | Channel 4 octave select
37
    0x12 | -xxx ---- | Channel 5 octave select
38
         |           |
39
    0x14 | ---- ---x | Channel 0 frequency enable (0 = off, 1 = on)
40
    0x14 | ---- --x- | Channel 1 frequency enable (0 = off, 1 = on)
41
    0x14 | ---- -x-- | Channel 2 frequency enable (0 = off, 1 = on)
42
    0x14 | ---- x--- | Channel 3 frequency enable (0 = off, 1 = on)
43
    0x14 | ---x ---- | Channel 4 frequency enable (0 = off, 1 = on)
44
    0x14 | --x- ---- | Channel 5 frequency enable (0 = off, 1 = on)
45
         |           |
46
    0x15 | ---- ---x | Channel 0 noise enable (0 = off, 1 = on)
47
    0x15 | ---- --x- | Channel 1 noise enable (0 = off, 1 = on)
48
    0x15 | ---- -x-- | Channel 2 noise enable (0 = off, 1 = on)
49
    0x15 | ---- x--- | Channel 3 noise enable (0 = off, 1 = on)
50
    0x15 | ---x ---- | Channel 4 noise enable (0 = off, 1 = on)
51
    0x15 | --x- ---- | Channel 5 noise enable (0 = off, 1 = on)
52
         |           |
53
    0x16 | ---- --xx | Noise generator parameters 0
54
    0x16 | --xx ---- | Noise generator parameters 1
55
         |           |
56
    0x18 | --xx xxxx | Envelope generator 0 parameters
57
    0x18 | x--- ---- | Envelope generator 0 control enable (0 = off, 1 = on)
58
    0x19 | --xx xxxx | Envelope generator 1 parameters
59
    0x19 | x--- ---- | Envelope generator 1 control enable (0 = off, 1 = on)
60
         |           |
61
    0x1c | ---- ---x | All channels enable (0 = off, 1 = on)
62
    0x1c | ---- --x- | Synch & Reset generators
63
 
64
***************************************************************************/
65
 
66
#include "../std.h"
67
#include "../emul.h"
68
#include "../vars.h"
69
 
70
#include "saa1099.h"
71
 
72
 
73
#define LEFT    0x00
74
#define RIGHT   0x01
75
 
76
static const int amplitude_lookup[16] =
77
{
78
     0*32767/16,  1*32767/16,  2*32767/16,  3*32767/16,
79
     4*32767/16,  5*32767/16,  6*32767/16,  7*32767/16,
80
     8*32767/16,  9*32767/16, 10*32767/16, 11*32767/16,
81
    12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16
82
};
83
 
84
static const UINT8 envelope[8][64] =
85
{
86
    /* zero amplitude */
87
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
91
    /* maximum amplitude */
92
    {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
93
     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
94
     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
95
     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, },
96
    /* single decay */
97
    {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
98
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
101
    /* repetitive decay */
102
    {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
103
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
104
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
105
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
106
    /* single triangular */
107
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
108
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
109
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
111
    /* repetitive triangular */
112
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
113
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
114
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
115
     15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
116
    /* single attack */
117
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
118
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
121
    /* repetitive attack */
122
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
123
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
124
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
125
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 }
126
};
127
 
128
static void saa1099_envelope(saa1099_state *saa, int ch)
129
{
130
    if (saa->env_enable[ch])
131
    {
132
        int step, mode, mask;
133
        /* step from 0..63 and then loop in steps 32..63 */
134
        step = saa->env_step[ch] =
135
            ((saa->env_step[ch] + 1) & 0x3f) | (saa->env_step[ch] & 0x20);
136
 
137
        mode = saa->env_mode[ch];
138
 
139
        if(saa->env_upd[ch])
140
        {
141
            if(
142
               ((mode == 1 || mode == 3 || mode == 7) && step && ((step & 0xF) == 0)) // 1, 3, 7
143
               ||
144
               ((mode == 5) && step && ((step & 0x1F) == 0)) // 5
145
               ||
146
               ((mode == 0 || mode == 2 || mode == 6) && step > 0x0F) // 0, 2, 6
147
               ||
148
               ((mode == 4) && step > 0x1F) // 4
149
              )
150
            {
151
                mode = saa->env_mode[ch] = saa->env_mode_buf[ch];
152
                saa->env_reverse_right[ch] = saa->env_reverse_right_buf[ch];
153
                saa->env_clock[ch] = saa->env_clock_buf[ch];
154
 
155
                /* reset the envelope */
156
                saa->env_step[ch] = 1;
157
                step = 1;
158
                saa->env_upd[ch] = false;
159
            }
160
        }
161
 
162
        mask = 15;
163
        if (saa->env_bits[ch])
164
            mask &= ~1;     /* 3 bit resolution, mask LSB */
165
 
166
        saa->channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask;
167
        if (saa->env_reverse_right[ch] & 0x01)
168
        {
169
            saa->channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask;
170
        }
171
        else
172
        {
173
            saa->channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask;
174
        }
175
    }
176
    else
177
    {
178
        /* envelope mode off, set all envelope factors to 16 */
179
        saa->channels[ch*3+0].envelope[ LEFT] =
180
        saa->channels[ch*3+1].envelope[ LEFT] =
181
        saa->channels[ch*3+2].envelope[ LEFT] =
182
        saa->channels[ch*3+0].envelope[RIGHT] =
183
        saa->channels[ch*3+1].envelope[RIGHT] =
184
        saa->channels[ch*3+2].envelope[RIGHT] = 16;
185
    }
186
}
187
 
188
 
189
void TSaa1099::update(unsigned TimeStamp)
190
{
191
    saa1099_state *saa = this;
192
    int ch;
193
 
194
    /* if the channels are disabled we're done */
195
    if (!saa->all_ch_enable)
196
    {
197
        /* init output data */
198
        SNDRENDER::update(TimeStamp, 0, 0);
199
        return;
200
    }
201
 
202
    for (ch = 0; ch < 2; ch++)
203
    {
204
        switch (saa->noise_params[ch])
205
        {
206
        case 0: saa->noise[ch].freq = 31250.0 * 2; break;
207
        case 1: saa->noise[ch].freq = 15625.0 * 2; break;
208
        case 2: saa->noise[ch].freq =  7812.5 * 2; break;
209
        case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break;
210
        }
211
    }
212
 
213
    /* fill all data needed */
214
    int output_l = 0, output_r = 0;
215
 
216
    /* for each channel */
217
    for (ch = 0; ch < 6; ch++)
218
    {
219
        if (saa->channels[ch].freq == 0.0)
220
            saa->channels[ch].freq = (double)((2*15625) << saa->channels[ch].octave) /
221
                (511.0 - (double)saa->channels[ch].frequency);
222
 
223
        /* check the actual position in the square wave */
224
        saa->channels[ch].counter -= saa->channels[ch].freq;
225
        while (saa->channels[ch].counter < 0)
226
        {
227
            /* calculate new frequency now after the half wave is updated */
228
            saa->channels[ch].freq = (double)((2*15625) << saa->channels[ch].octave) /
229
                (511.0 - (double)saa->channels[ch].frequency);
230
 
231
            saa->channels[ch].counter += saa->sample_rate;
232
            saa->channels[ch].level ^= 1;
233
 
234
            /* eventually clock the envelope counters */
235
            if (ch == 1 && saa->env_clock[0] == 0)
236
                saa1099_envelope(saa, 0);
237
            if (ch == 4 && saa->env_clock[1] == 0)
238
                saa1099_envelope(saa, 1);
239
        }
240
 
241
        /* if the noise is enabled */
242
        if (saa->channels[ch].noise_enable)
243
        {
244
            /* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */
245
            if (saa->noise[ch/3].level & 1)
246
            {
247
                /* subtract to avoid overflows, also use only half amplitude */
248
                output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2;
249
                output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2;
250
            }
251
        }
252
 
253
        /* if the square wave is enabled */
254
        if (saa->channels[ch].freq_enable)
255
        {
256
            /* if the channel level is high */
257
            if (saa->channels[ch].level & 1)
258
            {
259
                output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16;
260
                output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16;
261
            }
262
        }
263
        else if((ch == 2 || ch == 5) && saa->env_enable[ch/3])
264
        {
265
            output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16;
266
            output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16;
267
        }
268
    }
269
 
270
    for (ch = 0; ch < 2; ch++)
271
    {
272
        /* check the actual position in noise generator */
273
        saa->noise[ch].counter -= saa->noise[ch].freq;
274
        while (saa->noise[ch].counter < 0)
275
        {
276
            saa->noise[ch].counter += saa->sample_rate;
277
            if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) )
278
                saa->noise[ch].level = (saa->noise[ch].level << 1) | 1;
279
            else
280
                saa->noise[ch].level <<= 1;
281
        }
282
    }
283
 
284
    /* write sound data to the buffer */
784 DimkaM 285
    unsigned mix_l = unsigned(output_l / 6);
286
    unsigned mix_r = unsigned(output_r / 6);
716 lvd 287
    if ((mix_l ^ SNDRENDER::mix_l) | (mix_r ^ SNDRENDER::mix_r)) // similar check inside update()
288
        SNDRENDER::update(TimeStamp, mix_l, mix_r);
289
}
290
 
291
static const u32 SAM_SAA1099_CLK = 8000000; // Hz
292
 
293
TSaa1099::TSaa1099()
294
{
295
    saa1099_state *saa = this;
296
 
297
    memset(saa, 0, sizeof(saa1099_state));
298
 
299
    /* copy global parameters */
300
    saa1099_state::sample_rate = SAM_SAA1099_CLK / 256; // 31250 Hz
301
 
302
    for(unsigned ch = 0; ch < 6; ch++)
303
    {
304
        saa->channels[ch].envelope[ LEFT] =
305
        saa->channels[ch].envelope[RIGHT] = 16;
306
    }
307
}
308
 
309
void TSaa1099::WrCtl(u8 data)
310
{
311
    saa1099_state *saa = this;
312
 
313
    saa->selected_reg = data & 0x1f;
314
    if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19)
315
    {
316
        /* clock the envelope channels */
317
        if (saa->env_clock[0])
318
            saa1099_envelope(saa,0);
319
        if (saa->env_clock[1])
320
            saa1099_envelope(saa,1);
321
    }
322
}
323
 
324
 
325
void TSaa1099::WrData(unsigned TimeStamp, u8 data)
326
{
327
    saa1099_state *saa = this;
328
    int reg = saa->selected_reg;
329
    int ch;
330
 
331
    /* first update the stream to this point in time */
332
   if(TimeStamp)
333
       flush((TimeStamp * chip_clock_rate) / system_clock_rate);
334
 
335
    switch (reg)
336
    {
337
    /* channel i amplitude */
338
    case 0x00:  case 0x01:  case 0x02:  case 0x03:  case 0x04:  case 0x05:
339
        ch = reg & 7;
340
        saa->channels[ch].amp[LEFT] = data & 0x0f;
341
        saa->channels[ch].amp[RIGHT] = (data >> 4) & 0x0f;
342
 
343
        saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f];
344
        saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f];
345
 
346
        if(ch == 0)
347
        {
348
            if(saa->env_enable[0])
349
            {
350
                saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT] & ~1];
351
                saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT] & ~1];
352
            }
353
            else
354
            {
355
                saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT]];
356
                saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT]];
357
            }
358
        }
359
        else if(ch == 1)
360
        {
361
            if(saa->env_enable[1])
362
            {
363
                saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT] & ~1];
364
                saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT] & ~1];
365
            }
366
            else
367
            {
368
                saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT]];
369
                saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT]];
370
            }
371
        }
372
        break;
373
    /* channel i frequency */
374
    case 0x08:  case 0x09:  case 0x0a:  case 0x0b:  case 0x0c:  case 0x0d:
375
        ch = reg & 7;
376
        saa->channels[ch].frequency = data & 0xff;
377
        break;
378
    /* channel i octave */
379
    case 0x10:  case 0x11:  case 0x12:
380
        ch = (reg - 0x10) << 1;
381
        saa->channels[ch + 0].octave = data & 0x07;
382
        saa->channels[ch + 1].octave = (data >> 4) & 0x07;
383
        break;
384
    /* channel i frequency enable */
385
    case 0x14:
386
        saa->channels[0].freq_enable = data & 0x01;
387
        saa->channels[1].freq_enable = data & 0x02;
388
        saa->channels[2].freq_enable = data & 0x04;
389
        saa->channels[3].freq_enable = data & 0x08;
390
        saa->channels[4].freq_enable = data & 0x10;
391
        saa->channels[5].freq_enable = data & 0x20;
392
        break;
393
    /* channel i noise enable */
394
    case 0x15:
395
        saa->channels[0].noise_enable = data & 0x01;
396
        saa->channels[1].noise_enable = data & 0x02;
397
        saa->channels[2].noise_enable = data & 0x04;
398
        saa->channels[3].noise_enable = data & 0x08;
399
        saa->channels[4].noise_enable = data & 0x10;
400
        saa->channels[5].noise_enable = data & 0x20;
401
        break;
402
    /* noise generators parameters */
403
    case 0x16:
404
        saa->noise_params[0] = data & 0x03;
405
        saa->noise_params[1] = (data >> 4) & 0x03;
406
        break;
407
    /* envelope generators parameters */
408
    case 0x18:  case 0x19:
409
        ch = reg - 0x18;
410
 
411
        // direct
412
        saa->env_bits[ch] = data & 0x10;
413
        saa->env_enable[ch] = data & 0x80;
414
        if(!(data & 0x80))
415
            saa->env_step[ch] = 0; // reset envelope
416
 
417
        // buffered
418
        saa->env_reverse_right_buf[ch] = data & 0x01;
419
        saa->env_mode_buf[ch] = (data >> 1) & 0x07;
420
        saa->env_clock_buf[ch] = data & 0x20;
421
        saa->env_upd[ch] = true;
422
 
423
 
424
        if(ch == 0)
425
        {
426
            if(saa->env_enable[0])
427
            {
428
                saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT] & ~1];
429
                saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT] & ~1];
430
            }
431
            else
432
            {
433
                saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT]];
434
                saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT]];
435
            }
436
        }
437
 
438
        else if(ch == 1)
439
        {
440
            if(saa->env_enable[1])
441
            {
442
                saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT] & ~1];
443
                saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT] & ~1];
444
            }
445
            else
446
            {
447
                saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT]];
448
                saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT]];
449
            }
450
        }
451
        break;
452
    /* channels enable & reset generators */
453
    case 0x1c:
454
        saa->all_ch_enable = data & 0x01;
455
        saa->sync_state = data & 0x02;
456
        if (data & 0x02)
457
        {
458
            int i;
459
 
460
            /* Synch & Reset generators */
461
            for (i = 0; i < 6; i++)
462
            {
463
                saa->channels[i].level = 0;
464
                saa->channels[i].counter = 0.0;
465
            }
466
        }
467
        break;
468
    default:    /* Error! */
469
        ;
470
    }
471
}
472
 
473
void TSaa1099::start_frame(bufptr_t dst)
474
{
475
    SNDRENDER::start_frame(dst);
476
}
477
 
478
unsigned TSaa1099::end_frame(unsigned clk_ticks)
479
{
480
    uint64_t end_chip_tick = ((passed_clk_ticks + clk_ticks) * chip_clock_rate) / system_clock_rate;
481
 
482
    flush((unsigned)(end_chip_tick - passed_chip_ticks));
483
 
484
    unsigned Val = SNDRENDER::end_frame(t);
485
 
486
    passed_clk_ticks += clk_ticks;
487
    passed_chip_ticks += t;
488
    t = 0;
489
 
490
    return Val;
491
}
492
 
493
void TSaa1099::flush(unsigned chiptick)
494
{
495
    while(t < chiptick)
496
    {
497
        t++;
498
        update(t);
499
    }
500
}
501
 
502
void TSaa1099::set_timings(unsigned system_clock_rate, unsigned chip_clock_rate, unsigned sample_rate)
503
{
504
   chip_clock_rate /= 256;
505
 
506
   TSaa1099::system_clock_rate = system_clock_rate;
507
   TSaa1099::chip_clock_rate = chip_clock_rate;
508
   TSaa1099::saa1099_state::sample_rate = chip_clock_rate;
509
 
510
   SNDRENDER::set_timings(chip_clock_rate, sample_rate);
511
   passed_chip_ticks = passed_clk_ticks = 0;
512
   t = 0;
513
}
514
 
515
void TSaa1099::reset(unsigned TimeStamp)
516
{
517
    WrCtl(0x1C);
518
    WrData(TimeStamp, 2);
519
}
520
 
521
TSaa1099 Saa1099;