31
DSP_COPYRIGHT = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.",
46
SB_DMA_BUFSIZE = 65536,
49
SB_DMA_BLOCK_SAMPLES = 1024,
60
SB_DMA_CHANNEL_8BIT = SB_DMA1,
61
SB_DMA_CHANNEL_16BIT = SB_DMA5,
81
var DSP_COMMAND_SIZES = new Uint8Array(256);
82
var DSP_COMMAND_HANDLERS = [];
83
var MIXER_READ_HANDLERS = [];
84
var MIXER_WRITE_HANDLERS = [];
85
var MIXER_REGISTER_IS_LEGACY = new Uint8Array(256);
95
function SB16(cpu, bus)
104
this.write_buffer = new ByteQueue(DSP_BUFSIZE);
105
this.read_buffer = new ByteQueue(DSP_BUFSIZE);
106
this.read_buffer_lastvalue = 0;
109
this.command = DSP_NO_COMMAND;
110
this.command_size = 0;
113
this.mixer_current_address = 0;
114
this.mixer_registers = new Uint8Array(256);
118
this.dummy_speaker_enabled = false;
119
this.test_register = 0;
122
this.dsp_highspeed = false;
123
this.dsp_stereo = false;
124
this.dsp_16bit = false;
125
this.dsp_signed = false;
133
new FloatQueue(DSP_DACSIZE),
134
new FloatQueue(DSP_DACSIZE),
138
this.dma = cpu.devices.dma;
139
this.dma_sample_count = 0;
140
this.dma_bytes_count = 0;
141
this.dma_bytes_left = 0;
142
this.dma_bytes_block = 0;
144
this.dma_channel = 0;
145
this.dma_channel_8bit = SB_DMA_CHANNEL_8BIT;
146
this.dma_channel_16bit = SB_DMA_CHANNEL_16BIT;
147
this.dma_autoinit = false;
148
this.dma_buffer = new ArrayBuffer(SB_DMA_BUFSIZE);
149
this.dma_buffer_int8 = new Int8Array(this.dma_buffer);
150
this.dma_buffer_uint8 = new Uint8Array(this.dma_buffer);
151
this.dma_buffer_int16 = new Int16Array(this.dma_buffer);
152
this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer);
153
this.dma_syncbuffer = new SyncBuffer(this.dma_buffer);
154
this.dma_waiting_transfer = false;
155
this.dma_paused = false;
156
this.sampling_rate = 22050;
157
bus.send("dac-tell-sampling-rate", this.sampling_rate);
158
this.bytes_per_sample = 1;
161
this.e2_value = 0xAA;
165
this.asp_registers = new Uint8Array(256);
168
this.mpu_read_buffer = new ByteQueue(DSP_BUFSIZE);
169
this.mpu_read_buffer_lastvalue = 0;
172
this.fm_current_address0 = 0;
173
this.fm_current_address1 = 0;
174
this.fm_waveform_select_enable = false;
178
this.irq_triggered = new Uint8Array(0x10);
184
cpu.io.register_read_consecutive(0x220, this,
185
this.port2x0_read, this.port2x1_read, this.port2x2_read, this.port2x3_read);
186
cpu.io.register_read_consecutive(0x388, this,
187
this.port2x0_read, this.port2x1_read);
189
cpu.io.register_read_consecutive(0x224, this,
190
this.port2x4_read, this.port2x5_read);
192
cpu.io.register_read(0x226, this, this.port2x6_read);
193
cpu.io.register_read(0x227, this, this.port2x7_read);
194
cpu.io.register_read(0x228, this, this.port2x8_read);
195
cpu.io.register_read(0x229, this, this.port2x9_read);
197
cpu.io.register_read(0x22A, this, this.port2xA_read);
198
cpu.io.register_read(0x22B, this, this.port2xB_read);
199
cpu.io.register_read(0x22C, this, this.port2xC_read);
200
cpu.io.register_read(0x22D, this, this.port2xD_read);
202
cpu.io.register_read_consecutive(0x22E, this,
203
this.port2xE_read, this.port2xF_read);
205
cpu.io.register_write_consecutive(0x220, this,
206
this.port2x0_write, this.port2x1_write, this.port2x2_write, this.port2x3_write);
207
cpu.io.register_write_consecutive(0x388, this,
208
this.port2x0_write, this.port2x1_write);
210
cpu.io.register_write_consecutive(0x224, this,
211
this.port2x4_write, this.port2x5_write);
213
cpu.io.register_write(0x226, this, this.port2x6_write);
214
cpu.io.register_write(0x227, this, this.port2x7_write);
216
cpu.io.register_write_consecutive(0x228, this,
217
this.port2x8_write, this.port2x9_write);
219
cpu.io.register_write(0x22A, this, this.port2xA_write);
220
cpu.io.register_write(0x22B, this, this.port2xB_write);
221
cpu.io.register_write(0x22C, this, this.port2xC_write);
222
cpu.io.register_write(0x22D, this, this.port2xD_write);
223
cpu.io.register_write(0x22E, this, this.port2xE_write);
224
cpu.io.register_write(0x22F, this, this.port2xF_write);
226
cpu.io.register_read_consecutive(0x330, this, this.port3x0_read, this.port3x1_read);
227
cpu.io.register_write_consecutive(0x330, this, this.port3x0_write, this.port3x1_write);
229
this.dma.on_unmask(this.dma_on_unmask, this);
231
bus.register("dac-request-data", function()
233
this.dac_handle_request();
235
bus.register("speaker-has-initialized", function()
239
bus.send("speaker-confirm-initialized");
248
SB16.prototype.dsp_reset = function()
250
this.write_buffer.clear();
251
this.read_buffer.clear();
253
this.command = DSP_NO_COMMAND;
254
this.command_size = 0;
256
this.dummy_speaker_enabled = false;
257
this.test_register = 0;
259
this.dsp_highspeed = false;
260
this.dsp_stereo = false;
261
this.dsp_16bit = false;
262
this.dsp_signed = false;
264
this.dac_buffers[0].clear();
265
this.dac_buffers[1].clear();
267
this.dma_sample_count = 0;
268
this.dma_bytes_count = 0;
269
this.dma_bytes_left = 0;
270
this.dma_bytes_block = 0;
272
this.dma_channel = 0;
273
this.dma_autoinit = false;
274
this.dma_buffer_uint8.fill(0);
275
this.dma_waiting_transfer = false;
276
this.dma_paused = false;
278
this.e2_value = 0xAA;
281
this.sampling_rate = 22050;
282
this.bytes_per_sample = 1;
284
this.lower_irq(SB_IRQ_8BIT);
285
this.irq_triggered.fill(0);
287
this.asp_registers.fill(0);
288
this.asp_registers[5] = 0x01;
289
this.asp_registers[9] = 0xF8;
292
SB16.prototype.get_state = function()
298
state[2] = this.read_buffer_lastvalue;
300
state[3] = this.command;
301
state[4] = this.command_size;
303
state[5] = this.mixer_current_address;
304
state[6] = this.mixer_registers;
306
state[7] = this.dummy_speaker_enabled;
307
state[8] = this.test_register;
309
state[9] = this.dsp_highspeed;
310
state[10] = this.dsp_stereo;
311
state[11] = this.dsp_16bit;
312
state[12] = this.dsp_signed;
317
state[15] = this.dma_sample_count;
318
state[16] = this.dma_bytes_count;
319
state[17] = this.dma_bytes_left;
320
state[18] = this.dma_bytes_block;
321
state[19] = this.dma_irq;
322
state[20] = this.dma_channel;
323
state[21] = this.dma_channel_8bit;
324
state[22] = this.dma_channel_16bit;
325
state[23] = this.dma_autoinit;
326
state[24] = this.dma_buffer_uint8;
327
state[25] = this.dma_waiting_transfer;
328
state[26] = this.dma_paused;
329
state[27] = this.sampling_rate;
330
state[28] = this.bytes_per_sample;
332
state[29] = this.e2_value;
333
state[30] = this.e2_count;
335
state[31] = this.asp_registers;
338
state[33] = this.mpu_read_buffer_last_value;
340
state[34] = this.irq;
341
state[35] = this.irq_triggered;
347
SB16.prototype.set_state = function(state)
351
this.read_buffer_lastvalue = state[2];
353
this.command = state[3];
354
this.command_size = state[4];
356
this.mixer_current_address = state[5];
357
this.mixer_registers = state[6];
358
this.mixer_full_update();
360
this.dummy_speaker_enabled = state[7];
361
this.test_register = state[8];
363
this.dsp_highspeed = state[9];
364
this.dsp_stereo = state[10];
365
this.dsp_16bit = state[11];
366
this.dsp_signed = state[12];
371
this.dma_sample_count = state[15];
372
this.dma_bytes_count = state[16];
373
this.dma_bytes_left = state[17];
374
this.dma_bytes_block = state[18];
375
this.dma_irq = state[19];
376
this.dma_channel = state[20];
377
this.dma_channel_8bit = state[21];
378
this.dma_channel_16bit = state[22];
379
this.dma_autoinit = state[23];
380
this.dma_buffer_uint8 = state[24];
381
this.dma_waiting_transfer = state[25];
382
this.dma_paused = state[26];
383
this.sampling_rate = state[27];
384
this.bytes_per_sample = state[28];
386
this.e2_value = state[29];
387
this.e2_count = state[30];
389
this.asp_registers = state[31];
392
this.mpu_read_buffer_last_value = state[33];
394
this.irq = state[34];
395
this.irq_triggered = state[35];
398
this.dma_buffer = this.dma_buffer_uint8.buffer;
399
this.dma_buffer_int8 = new Int8Array(this.dma_buffer);
400
this.dma_buffer_int16 = new Int16Array(this.dma_buffer);
401
this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer);
402
this.dma_syncbuffer = new SyncBuffer(this.dma_buffer);
406
this.bus.send("dac-disable");
410
this.bus.send("dac-enable");
418
SB16.prototype.port2x0_read = function()
420
dbg_log("220 read: fm music status port (unimplemented)", LOG_SB16);
424
SB16.prototype.port2x1_read = function()
426
dbg_log("221 read: fm music data port (write only)", LOG_SB16);
430
SB16.prototype.port2x2_read = function()
432
dbg_log("222 read: advanced fm music status port (unimplemented)", LOG_SB16);
436
SB16.prototype.port2x3_read = function()
438
dbg_log("223 read: advanced music data port (write only)", LOG_SB16);
443
SB16.prototype.port2x4_read = function()
445
dbg_log("224 read: mixer address port", LOG_SB16);
446
return this.mixer_current_address;
450
SB16.prototype.port2x5_read = function()
452
dbg_log("225 read: mixer data port", LOG_SB16);
453
return this.mixer_read(this.mixer_current_address);
456
SB16.prototype.port2x6_read = function()
458
dbg_log("226 read: (write only)", LOG_SB16);
462
SB16.prototype.port2x7_read = function()
464
dbg_log("227 read: undocumented", LOG_SB16);
468
SB16.prototype.port2x8_read = function()
470
dbg_log("228 read: fm music status port (unimplemented)", LOG_SB16);
474
SB16.prototype.port2x9_read = function()
476
dbg_log("229 read: fm music data port (write only)", LOG_SB16);
482
SB16.prototype.port2xA_read = function()
484
dbg_log("22A read: read data", LOG_SB16);
485
if(this.read_buffer.length)
487
this.read_buffer_lastvalue = this.read_buffer.shift();
489
dbg_log(" <- " + this.read_buffer_lastvalue + " " + h(this.read_buffer_lastvalue) + " '" + String.fromCharCode(this.read_buffer_lastvalue) + "'", LOG_SB16);
490
return this.read_buffer_lastvalue;
493
SB16.prototype.port2xB_read = function()
495
dbg_log("22B read: undocumented", LOG_SB16);
501
SB16.prototype.port2xC_read = function()
503
dbg_log("22C read: write-buffer status", LOG_SB16);
508
SB16.prototype.port2xD_read = function()
510
dbg_log("22D read: undocumented", LOG_SB16);
517
SB16.prototype.port2xE_read = function()
519
dbg_log("22E read: read-buffer status / irq 8bit ack.", LOG_SB16);
520
if(this.irq_triggered[SB_IRQ_8BIT])
522
this.lower_irq(SB_IRQ_8BIT);
524
var ready = this.read_buffer.length && !this.dsp_highspeed;
525
return (ready << 7) | 0x7F;
529
SB16.prototype.port2xF_read = function()
531
dbg_log("22F read: irq 16bit ack", LOG_SB16);
532
this.lower_irq(SB_IRQ_16BIT);
538
SB16.prototype.port2x0_write = function(value)
540
dbg_log("220 write: (unimplemented) fm register 0 address = " + h(value), LOG_SB16);
541
this.fm_current_address0 = 0;
545
SB16.prototype.port2x1_write = function(value)
547
dbg_log("221 write: (unimplemented) fm register 0 data = " + h(value), LOG_SB16);
548
var handler = FM_HANDLERS[this.fm_current_address0];
551
handler = this.fm_default_write;
553
handler.call(this, value, 0, this.fm_current_address0);
557
SB16.prototype.port2x2_write = function(value)
559
dbg_log("222 write: (unimplemented) fm register 1 address = " + h(value), LOG_SB16);
560
this.fm_current_address1 = 0;
564
SB16.prototype.port2x3_write = function(value)
566
dbg_log("223 write: (unimplemented) fm register 1 data =" + h(value), LOG_SB16);
567
var handler = FM_HANDLERS[this.fm_current_address1];
570
handler = this.fm_default_write;
572
handler.call(this, value, 1, this.fm_current_address1);
576
SB16.prototype.port2x4_write = function(value)
578
dbg_log("224 write: mixer address = " + h(value), LOG_SB16);
579
this.mixer_current_address = value;
583
SB16.prototype.port2x5_write = function(value)
585
dbg_log("225 write: mixer data = " + h(value), LOG_SB16);
586
this.mixer_write(this.mixer_current_address, value);
591
SB16.prototype.port2x6_write = function(yesplease)
593
dbg_log("226 write: reset = " + h(yesplease), LOG_SB16);
595
if(this.dsp_highspeed)
597
dbg_log(" -> exit highspeed", LOG_SB16);
598
this.dsp_highspeed = false;
602
dbg_log(" -> reset", LOG_SB16);
607
this.read_buffer.clear();
608
this.read_buffer.push(0xAA);
611
SB16.prototype.port2x7_write = function(value)
613
dbg_log("227 write: undocumented", LOG_SB16);
616
SB16.prototype.port2x8_write = function(value)
618
dbg_log("228 write: fm music register port (unimplemented)", LOG_SB16);
621
SB16.prototype.port2x9_write = function(value)
623
dbg_log("229 write: fm music data port (unimplemented)", LOG_SB16);
626
SB16.prototype.port2xA_write = function(value)
628
dbg_log("22A write: dsp read data port (read only)", LOG_SB16);
631
SB16.prototype.port2xB_write = function(value)
633
dbg_log("22B write: undocumented", LOG_SB16);
638
SB16.prototype.port2xC_write = function(value)
640
dbg_log("22C write: write command/data", LOG_SB16);
642
if(this.command === DSP_NO_COMMAND)
645
dbg_log("22C write: command = " + h(value), LOG_SB16);
646
this.command = value;
647
this.write_buffer.clear();
648
this.command_size = DSP_COMMAND_SIZES[value];
653
dbg_log("22C write: data: " + h(value), LOG_SB16);
654
this.write_buffer.push(value);
658
if(this.write_buffer.length >= this.command_size)
664
SB16.prototype.port2xD_write = function(value)
666
dbg_log("22D write: undocumented", LOG_SB16);
669
SB16.prototype.port2xE_write = function(value)
671
dbg_log("22E write: dsp read buffer status (read only)", LOG_SB16);
674
SB16.prototype.port2xF_write = function(value)
676
dbg_log("22F write: undocumented", LOG_SB16);
681
SB16.prototype.port3x0_read = function()
683
dbg_log("330 read: mpu data", LOG_SB16);
685
if(this.mpu_read_buffer.length)
687
this.mpu_read_buffer_lastvalue = this.mpu_read_buffer.shift();
689
dbg_log(" <- " + h(this.mpu_read_buffer_lastvalue), LOG_SB16);
691
return this.mpu_read_buffer_lastvalue;
693
SB16.prototype.port3x0_write = function(value)
695
dbg_log("330 write: mpu data (unimplemented) : " + h(value), LOG_SB16);
699
SB16.prototype.port3x1_read = function()
701
dbg_log("331 read: mpu status", LOG_SB16);
705
status |= 0x80 * !this.mpu_read_buffer.length;
711
SB16.prototype.port3x1_write = function(value)
713
dbg_log("331 write: mpu command: " + h(value), LOG_SB16);
717
this.mpu_read_buffer.clear();
718
this.mpu_read_buffer.push(0xFE);
726
SB16.prototype.command_do = function()
728
var handler = DSP_COMMAND_HANDLERS[this.command];
731
handler = this.dsp_default_handler;
736
this.command = DSP_NO_COMMAND;
737
this.command_size = 0;
738
this.write_buffer.clear();
741
SB16.prototype.dsp_default_handler = function()
743
dbg_log("Unhandled command: " + h(this.command), LOG_SB16);
751
function register_dsp_command(commands, size, handler)
755
handler = SB16.prototype.dsp_default_handler;
757
for(var i = 0; i < commands.length; i++)
759
DSP_COMMAND_SIZES[commands[i]] = size;
760
DSP_COMMAND_HANDLERS[commands[i]] = handler;
764
function any_first_digit(base)
767
for(var i = 0; i < 16; i++)
769
commands.push(base + i);
775
register_dsp_command([0x0E], 2, function()
777
this.asp_registers[this.write_buffer.shift()] = this.write_buffer.shift();
781
register_dsp_command([0x0F], 1, function()
783
this.read_buffer.clear();
784
this.read_buffer.push(this.asp_registers[this.write_buffer.shift()]);
788
register_dsp_command([0x10], 1, function()
790
var value = audio_normalize(this.write_buffer.shift(), 127.5, -1);
792
this.dac_buffers[0].push(value);
793
this.dac_buffers[1].push(value);
794
this.bus.send("dac-enable");
798
register_dsp_command([0x14, 0x15], 2, function()
800
this.dma_irq = SB_IRQ_8BIT;
801
this.dma_channel = this.dma_channel_8bit;
802
this.dma_autoinit = false;
803
this.dsp_signed = false;
804
this.dsp_16bit = false;
805
this.dsp_highspeed = false;
806
this.dma_transfer_size_set();
807
this.dma_transfer_start();
811
register_dsp_command([0x16], 2);
815
register_dsp_command([0x17], 2);
818
register_dsp_command([0x1C], 0, function()
820
this.dma_irq = SB_IRQ_8BIT;
821
this.dma_channel = this.dma_channel_8bit;
822
this.dma_autoinit = true;
823
this.dsp_signed = false;
824
this.dsp_16bit = false;
825
this.dsp_highspeed = false;
826
this.dma_transfer_start();
831
register_dsp_command([0x1F], 0);
834
register_dsp_command([0x20], 0, function()
837
this.read_buffer.clear();
838
this.read_buffer.push(0x7f);
842
register_dsp_command([0x24], 2);
845
register_dsp_command([0x2C], 0);
848
register_dsp_command([0x30], 0);
851
register_dsp_command([0x31], 0);
854
register_dsp_command([0x34], 0);
857
register_dsp_command([0x35], 0);
860
register_dsp_command([0x36], 0);
863
register_dsp_command([0x37], 0);
866
register_dsp_command([0x38], 0);
869
register_dsp_command([0x40], 1, function()
872
this.sampling_rate_change(
873
1000000 / (256 - this.write_buffer.shift()) / this.get_channel_count()
879
register_dsp_command([0x41, 0x42], 2, function()
881
this.sampling_rate_change((this.write_buffer.shift() << 8) | this.write_buffer.shift());
885
register_dsp_command([0x48], 2, function()
891
this.dma_transfer_size_set();
895
register_dsp_command([0x74], 2);
899
register_dsp_command([0x75], 2);
902
register_dsp_command([0x76], 2);
906
register_dsp_command([0x77], 2);
910
register_dsp_command([0x7D], 0);
914
register_dsp_command([0x7F], 0);
917
register_dsp_command([0x80], 2);
920
register_dsp_command([0x90], 0, function()
922
this.dma_irq = SB_IRQ_8BIT;
923
this.dma_channel = this.dma_channel_8bit;
924
this.dma_autoinit = true;
925
this.dsp_signed = false;
926
this.dsp_highspeed = true;
927
this.dsp_16bit = false;
928
this.dma_transfer_start();
932
register_dsp_command([0x91], 0);
935
register_dsp_command([0x98], 0);
938
register_dsp_command([0x99], 0);
941
register_dsp_command([0xA0], 0);
944
register_dsp_command([0xA8], 0);
947
register_dsp_command(any_first_digit(0xB0), 3, function()
949
if(this.command & (1 << 3))
952
this.dsp_default_handler();
955
var mode = this.write_buffer.shift();
956
this.dma_irq = SB_IRQ_16BIT;
957
this.dma_channel = this.dma_channel_16bit;
958
this.dma_autoinit = !!(this.command & (1 << 2));
959
this.dsp_signed = !!(mode & (1 << 4));
960
this.dsp_stereo = !!(mode & (1 << 5));
961
this.dsp_16bit = true;
962
this.dma_transfer_size_set();
963
this.dma_transfer_start();
967
register_dsp_command(any_first_digit(0xC0), 3, function()
969
if(this.command & (1 << 3))
972
this.dsp_default_handler();
975
var mode = this.write_buffer.shift();
976
this.dma_irq = SB_IRQ_8BIT;
977
this.dma_channel = this.dma_channel_8bit;
978
this.dma_autoinit = !!(this.command & (1 << 2));
979
this.dsp_signed = !!(mode & (1 << 4));
980
this.dsp_stereo = !!(mode & (1 << 5));
981
this.dsp_16bit = false;
982
this.dma_transfer_size_set();
983
this.dma_transfer_start();
987
register_dsp_command([0xD0], 0, function()
989
this.dma_paused = true;
990
this.bus.send("dac-disable");
995
register_dsp_command([0xD1], 0, function()
997
this.dummy_speaker_enabled = true;
1002
register_dsp_command([0xD3], 0, function()
1004
this.dummy_speaker_enabled = false;
1008
register_dsp_command([0xD4], 0, function()
1010
this.dma_paused = false;
1011
this.bus.send("dac-enable");
1015
register_dsp_command([0xD5], 0, function()
1017
this.dma_paused = true;
1018
this.bus.send("dac-disable");
1022
register_dsp_command([0xD6], 0, function()
1024
this.dma_paused = false;
1025
this.bus.send("dac-enable");
1029
register_dsp_command([0xD8], 0, function()
1031
this.read_buffer.clear();
1032
this.read_buffer.push(this.dummy_speaker_enabled * 0xFF);
1037
register_dsp_command([0xD9, 0xDA], 0, function()
1039
this.dma_autoinit = false;
1043
register_dsp_command([0xE0], 1, function()
1045
this.read_buffer.clear();
1046
this.read_buffer.push(~this.write_buffer.shift());
1050
register_dsp_command([0xE1], 0, function()
1052
this.read_buffer.clear();
1053
this.read_buffer.push(4);
1054
this.read_buffer.push(5);
1058
register_dsp_command([0xE2], 1);
1061
register_dsp_command([0xE3], 0, function()
1063
this.read_buffer.clear();
1064
for(var i = 0; i < DSP_COPYRIGHT.length; i++)
1066
this.read_buffer.push(DSP_COPYRIGHT.charCodeAt(i));
1069
this.read_buffer.push(0);
1073
register_dsp_command([0xE4], 1, function()
1075
this.test_register = this.write_buffer.shift();
1079
register_dsp_command([0xE8], 0, function()
1081
this.read_buffer.clear();
1082
this.read_buffer.push(this.test_register);
1086
register_dsp_command([0xF2, 0xF3], 0, function()
1092
var SB_F9 = new Uint8Array(256);
1096
register_dsp_command([0xF9], 1, function()
1098
var input = this.write_buffer.shift();
1099
dbg_log("dsp 0xf9: unknown function. input: " + input, LOG_SB16);
1101
this.read_buffer.clear();
1102
this.read_buffer.push(SB_F9[input]);
1109
SB16.prototype.mixer_read = function(address)
1111
var handler = MIXER_READ_HANDLERS[address];
1115
data = handler.call(this);
1119
data = this.mixer_registers[address];
1120
dbg_log("unhandled mixer register read. addr:" + h(address) + " data:" + h(data), LOG_SB16);
1125
SB16.prototype.mixer_write = function(address, data)
1127
var handler = MIXER_WRITE_HANDLERS[address];
1130
handler.call(this, data);
1134
dbg_log("unhandled mixer register write. addr:" + h(address) + " data:" + h(data), LOG_SB16);
1138
SB16.prototype.mixer_default_read = function()
1140
dbg_log("mixer register read. addr:" + h(this.mixer_current_address), LOG_SB16);
1141
return this.mixer_registers[this.mixer_current_address];
1144
SB16.prototype.mixer_default_write = function(data)
1146
dbg_log("mixer register write. addr:" + h(this.mixer_current_address) + " data:" + h(data), LOG_SB16);
1147
this.mixer_registers[this.mixer_current_address] = data;
1150
SB16.prototype.mixer_reset = function()
1155
this.mixer_registers[0x04] = 12 << 4 | 12;
1156
this.mixer_registers[0x22] = 12 << 4 | 12;
1157
this.mixer_registers[0x26] = 12 << 4 | 12;
1158
this.mixer_registers[0x28] = 0;
1159
this.mixer_registers[0x2E] = 0;
1160
this.mixer_registers[0x0A] = 0;
1161
this.mixer_registers[0x30] = 24 << 3;
1162
this.mixer_registers[0x31] = 24 << 3;
1163
this.mixer_registers[0x32] = 24 << 3;
1164
this.mixer_registers[0x33] = 24 << 3;
1165
this.mixer_registers[0x34] = 24 << 3;
1166
this.mixer_registers[0x35] = 24 << 3;
1167
this.mixer_registers[0x36] = 0;
1168
this.mixer_registers[0x37] = 0;
1169
this.mixer_registers[0x38] = 0;
1170
this.mixer_registers[0x39] = 0;
1171
this.mixer_registers[0x3B] = 0;
1172
this.mixer_registers[0x3C] = 0x1F;
1173
this.mixer_registers[0x3D] = 0x15;
1174
this.mixer_registers[0x3E] = 0x0B;
1175
this.mixer_registers[0x3F] = 0;
1176
this.mixer_registers[0x40] = 0;
1177
this.mixer_registers[0x41] = 0;
1178
this.mixer_registers[0x42] = 0;
1179
this.mixer_registers[0x43] = 0;
1180
this.mixer_registers[0x44] = 8 << 4;
1181
this.mixer_registers[0x45] = 8 << 4;
1182
this.mixer_registers[0x46] = 8 << 4;
1183
this.mixer_registers[0x47] = 8 << 4;
1185
this.mixer_full_update();
1188
SB16.prototype.mixer_full_update = function()
1191
for(var i = 1; i < this.mixer_registers.length; i++)
1193
if(MIXER_REGISTER_IS_LEGACY[i])
1199
this.mixer_write(i, this.mixer_registers[i]);
1207
function register_mixer_read(address, handler)
1211
handler = SB16.prototype.mixer_default_read;
1213
MIXER_READ_HANDLERS[address] = handler;
1220
function register_mixer_write(address, handler)
1224
handler = SB16.prototype.mixer_default_write;
1226
MIXER_WRITE_HANDLERS[address] = handler;
1230
function register_mixer_legacy(address_old, address_new_left, address_new_right)
1232
MIXER_REGISTER_IS_LEGACY[address_old] = 1;
1235
MIXER_READ_HANDLERS[address_old] = function()
1237
var left = this.mixer_registers[address_new_left] & 0xF0;
1238
var right = this.mixer_registers[address_new_right] >>> 4;
1239
return left | right;
1243
MIXER_WRITE_HANDLERS[address_old] = function(data)
1245
this.mixer_registers[address_old] = data;
1246
var prev_left = this.mixer_registers[address_new_left];
1247
var prev_right = this.mixer_registers[address_new_right];
1248
var left = (data & 0xF0) | (prev_left & 0x0F);
1249
var right = (data << 4 & 0xF0) | (prev_right & 0x0F);
1251
this.mixer_write(address_new_left, left);
1252
this.mixer_write(address_new_right, right);
1261
function register_mixer_volume(address, mixer_source, channel)
1263
MIXER_READ_HANDLERS[address] = SB16.prototype.mixer_default_read;
1266
MIXER_WRITE_HANDLERS[address] = function(data)
1268
this.mixer_registers[address] = data;
1269
this.bus.send("mixer-volume",
1279
register_mixer_read(0x00, function()
1284
register_mixer_write(0x00);
1287
register_mixer_legacy(0x04, 0x32, 0x33);
1299
register_mixer_legacy(0x22, 0x30, 0x31);
1301
register_mixer_legacy(0x26, 0x34, 0x35);
1303
register_mixer_legacy(0x28, 0x36, 0x37);
1305
register_mixer_legacy(0x2E, 0x38, 0x39);
1308
register_mixer_volume(0x30, MIXER_SRC_MASTER, MIXER_CHANNEL_LEFT);
1310
register_mixer_volume(0x31, MIXER_SRC_MASTER, MIXER_CHANNEL_RIGHT);
1312
register_mixer_volume(0x32, MIXER_SRC_DAC, MIXER_CHANNEL_LEFT);
1314
register_mixer_volume(0x33, MIXER_SRC_DAC, MIXER_CHANNEL_RIGHT);
1331
register_mixer_read(0x3B);
1332
register_mixer_write(0x3B, function(data)
1334
this.mixer_registers[0x3B] = data;
1335
this.bus.send("mixer-volume", [MIXER_SRC_PCSPEAKER, MIXER_CHANNEL_BOTH, (data >>> 6) * 6 - 18]);
1377
register_mixer_read(0x41);
1378
register_mixer_write(0x41, function(data)
1380
this.mixer_registers[0x41] = data;
1381
this.bus.send("mixer-gain-left", (data >>> 6) * 6);
1385
register_mixer_read(0x42);
1386
register_mixer_write(0x42, function(data)
1388
this.mixer_registers[0x42] = data;
1389
this.bus.send("mixer-gain-right", (data >>> 6) * 6);
1397
register_mixer_read(0x44);
1398
register_mixer_write(0x44, function(data)
1400
this.mixer_registers[0x44] = data;
1402
this.bus.send("mixer-treble-left", data - (data < 16 ? 14 : 16));
1406
register_mixer_read(0x45);
1407
register_mixer_write(0x45, function(data)
1409
this.mixer_registers[0x45] = data;
1411
this.bus.send("mixer-treble-right", data - (data < 16 ? 14 : 16));
1415
register_mixer_read(0x46);
1416
register_mixer_write(0x46, function(data)
1418
this.mixer_registers[0x46] = data;
1420
this.bus.send("mixer-bass-right", data - (data < 16 ? 14 : 16));
1424
register_mixer_read(0x47);
1425
register_mixer_write(0x47, function(data)
1427
this.mixer_registers[0x47] = data;
1429
this.bus.send("mixer-bass-right", data - (data < 16 ? 14 : 16));
1433
register_mixer_read(0x80, function()
1437
case SB_IRQ2: return 0x1;
1438
case SB_IRQ5: return 0x2;
1439
case SB_IRQ7: return 0x4;
1440
case SB_IRQ10: return 0x8;
1441
default: return 0x0;
1444
register_mixer_write(0x80, function(bits)
1446
if(bits & 0x1) this.irq = SB_IRQ2;
1447
if(bits & 0x2) this.irq = SB_IRQ5;
1448
if(bits & 0x4) this.irq = SB_IRQ7;
1449
if(bits & 0x8) this.irq = SB_IRQ10;
1453
register_mixer_read(0x81, function()
1456
switch(this.dma_channel_8bit)
1458
case SB_DMA0: ret |= 0x1; break;
1459
case SB_DMA1: ret |= 0x2; break;
1461
case SB_DMA3: ret |= 0x8; break;
1463
switch(this.dma_channel_16bit)
1466
case SB_DMA5: ret |= 0x20; break;
1467
case SB_DMA6: ret |= 0x40; break;
1468
case SB_DMA7: ret |= 0x80; break;
1472
register_mixer_write(0x81, function(bits)
1474
if(bits & 0x1) this.dma_channel_8bit = SB_DMA0;
1475
if(bits & 0x2) this.dma_channel_8bit = SB_DMA1;
1476
if(bits & 0x8) this.dma_channel_8bit = SB_DMA3;
1477
if(bits & 0x20) this.dma_channel_16bit = SB_DMA5;
1478
if(bits & 0x40) this.dma_channel_16bit = SB_DMA6;
1479
if(bits & 0x80) this.dma_channel_16bit = SB_DMA7;
1483
register_mixer_read(0x82, function()
1486
for(var i = 0; i < 16; i++)
1488
ret |= i * this.irq_triggered[i];
1497
SB16.prototype.fm_default_write = function(data, register, address)
1499
dbg_log("unhandled fm register write. addr:" + register + "|" + h(address) + " data:" + h(data), LOG_SB16);
1507
function register_fm_write(addresses, handler)
1511
handler = SB16.prototype.fm_default_write;
1513
for(var i = 0; i < addresses.length; i++)
1515
FM_HANDLERS[addresses[i]] = handler;
1519
function between(start, end)
1522
for(var i = start; i <= end; i++)
1529
var SB_FM_OPERATORS_BY_OFFSET = new Uint8Array(32);
1530
SB_FM_OPERATORS_BY_OFFSET[0x00] = 0;
1531
SB_FM_OPERATORS_BY_OFFSET[0x01] = 1;
1532
SB_FM_OPERATORS_BY_OFFSET[0x02] = 2;
1533
SB_FM_OPERATORS_BY_OFFSET[0x03] = 3;
1534
SB_FM_OPERATORS_BY_OFFSET[0x04] = 4;
1535
SB_FM_OPERATORS_BY_OFFSET[0x05] = 5;
1536
SB_FM_OPERATORS_BY_OFFSET[0x08] = 6;
1537
SB_FM_OPERATORS_BY_OFFSET[0x09] = 7;
1538
SB_FM_OPERATORS_BY_OFFSET[0x0A] = 8;
1539
SB_FM_OPERATORS_BY_OFFSET[0x0B] = 9;
1540
SB_FM_OPERATORS_BY_OFFSET[0x0C] = 10;
1541
SB_FM_OPERATORS_BY_OFFSET[0x0D] = 11;
1542
SB_FM_OPERATORS_BY_OFFSET[0x10] = 12;
1543
SB_FM_OPERATORS_BY_OFFSET[0x11] = 13;
1544
SB_FM_OPERATORS_BY_OFFSET[0x12] = 14;
1545
SB_FM_OPERATORS_BY_OFFSET[0x13] = 15;
1546
SB_FM_OPERATORS_BY_OFFSET[0x14] = 16;
1547
SB_FM_OPERATORS_BY_OFFSET[0x15] = 17;
1549
function get_fm_operator(register, offset)
1551
return register * 18 + SB_FM_OPERATORS_BY_OFFSET[offset];
1554
register_fm_write([0x01], function(bits, register, address)
1556
this.fm_waveform_select_enable[register] = bits & 0x20 > 0;
1557
this.fm_update_waveforms();
1561
register_fm_write([0x02]);
1564
register_fm_write([0x03]);
1566
register_fm_write([0x04], function(bits, register, address)
1586
register_fm_write([0x05], function(bits, register, address)
1591
this.fm_default_write(bits, register, address);
1597
register_fm_write([0x08], function(bits, register, address)
1603
register_fm_write(between(0x20, 0x35), function(bits, register, address)
1605
var operator = get_fm_operator(register, address - 0x20);
1613
register_fm_write(between(0x40, 0x55), function(bits, register, address)
1615
var operator = get_fm_operator(register, address - 0x40);
1620
register_fm_write(between(0x60, 0x75), function(bits, register, address)
1622
var operator = get_fm_operator(register, address - 0x60);
1627
register_fm_write(between(0x80, 0x95), function(bits, register, address)
1629
var operator = get_fm_operator(register, address - 0x80);
1634
register_fm_write(between(0xA0, 0xA8), function(bits, register, address)
1636
var channel = address - 0xA0;
1640
register_fm_write(between(0xB0, 0xB8), function(bits, register, address)
1647
register_fm_write([0xBD], function(bits, register, address)
1659
register_fm_write(between(0xC0, 0xC8), function(bits, register, address)
1667
register_fm_write(between(0xE0, 0xF5), function(bits, register, address)
1669
var operator = get_fm_operator(register, address - 0xE0);
1677
SB16.prototype.fm_update_waveforms = function()
1686
SB16.prototype.sampling_rate_change = function(rate)
1688
this.sampling_rate = rate;
1689
this.bus.send("dac-tell-sampling-rate", rate);
1692
SB16.prototype.get_channel_count = function()
1694
return this.dsp_stereo ? 2 : 1;
1697
SB16.prototype.dma_transfer_size_set = function()
1699
this.dma_sample_count = 1 + (this.write_buffer.shift() << 0) + (this.write_buffer.shift() << 8);
1702
SB16.prototype.dma_transfer_start = function()
1704
dbg_log("begin dma transfer", LOG_SB16);
1708
this.bytes_per_sample = 1;
1709
if(this.dsp_16bit) this.bytes_per_sample *= 2;
1717
this.dma_bytes_count = this.dma_sample_count * this.bytes_per_sample;
1718
this.dma_bytes_block = SB_DMA_BLOCK_SAMPLES * this.bytes_per_sample;
1721
var max_bytes_block = Math.max(this.dma_bytes_count >> 2 & ~0x3, 32);
1722
this.dma_bytes_block = Math.min(max_bytes_block, this.dma_bytes_block);
1725
this.dma_waiting_transfer = true;
1726
if(!this.dma.channel_mask[this.dma_channel])
1728
this.dma_on_unmask(this.dma_channel);
1732
SB16.prototype.dma_on_unmask = function(channel)
1734
if(channel !== this.dma_channel || !this.dma_waiting_transfer)
1741
this.dma_waiting_transfer = false;
1742
this.dma_bytes_left = this.dma_bytes_count;
1743
this.dma_paused = false;
1744
this.bus.send("dac-enable");
1747
SB16.prototype.dma_transfer_next = function()
1749
dbg_log("dma transfering next block", LOG_SB16);
1751
var size = Math.min(this.dma_bytes_left, this.dma_bytes_block);
1752
var samples = Math.floor(size / this.bytes_per_sample);
1754
this.dma.do_write(this.dma_syncbuffer, 0, size, this.dma_channel, (error) =>
1756
dbg_log("dma block transfer " + (error ? "unsuccessful" : "successful"), LOG_SB16);
1759
this.dma_to_dac(samples);
1760
this.dma_bytes_left -= size;
1762
if(!this.dma_bytes_left)
1765
this.raise_irq(this.dma_irq);
1767
if(this.dma_autoinit)
1770
this.dma_bytes_left = this.dma_bytes_count;
1776
SB16.prototype.dma_to_dac = function(sample_count)
1778
var amplitude = this.dsp_16bit ? 32767.5 : 127.5;
1779
var offset = this.dsp_signed ? 0 : -1;
1780
var repeats = this.dsp_stereo ? 1 : 2;
1785
buffer = this.dsp_signed ? this.dma_buffer_int16 : this.dma_buffer_uint16;
1789
buffer = this.dsp_signed ? this.dma_buffer_int8 : this.dma_buffer_uint8;
1793
for(var i = 0; i < sample_count; i++)
1795
var sample = audio_normalize(buffer[i], amplitude, offset);
1796
for(var j = 0; j < repeats; j++)
1798
this.dac_buffers[channel].push(sample);
1806
SB16.prototype.dac_handle_request = function()
1808
if(!this.dma_bytes_left || this.dma_paused)
1815
this.dma_transfer_next();
1819
SB16.prototype.dac_send = function()
1821
if(!this.dac_buffers[0].length)
1826
var out0 = this.dac_buffers[0].shift_block(this.dac_buffers[0].length);
1827
var out1 = this.dac_buffers[1].shift_block(this.dac_buffers[1].length);
1828
this.bus.send("dac-send-data", [out0, out1], [out0.buffer, out1.buffer]);
1831
SB16.prototype.raise_irq = function(type)
1833
dbg_log("raise irq", LOG_SB16);
1834
this.irq_triggered[type] = 1;
1835
this.cpu.device_raise_irq(this.irq);
1838
SB16.prototype.lower_irq = function(type)
1840
dbg_log("lower irq", LOG_SB16);
1841
this.irq_triggered[type] = 0;
1842
this.cpu.device_lower_irq(this.irq);
1849
function audio_normalize(value, amplitude, offset)
1851
return audio_clip(value / amplitude + offset, -1, 1);
1854
function audio_clip(value, low, high)
1856
return (value < low) * low + (value > high) * high + (low <= value && value <= high) * value;