1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
|
/***************************************************************************
Atari Jaguar hardware
****************************************************************************
------------------------------------------------------------
JERRY REGISTERS
------------------------------------------------------------
F10000-F13FFF R/W xxxxxxxx xxxxxxxx Jerry
F10000 W xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler
F10004 W xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider
F10008 W xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler
F1000C W xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider
F10010 W ------xx xxxxxxxx CLK1 - processor clock divider
F10012 W ------xx xxxxxxxx CLK2 - video clock divider
F10014 W -------- --xxxxxx CLK3 - chroma clock divider
F10020 R/W ---xxxxx ---xxxxx JINTCTRL - interrupt control register
W ---x---- -------- (J_SYNCLR - clear synchronous serial intf ints)
W ----x--- -------- (J_ASYNCLR - clear asynchronous serial intf ints)
W -----x-- -------- (J_TIM2CLR - clear timer 2 [tempo] interrupts)
W ------x- -------- (J_TIM1CLR - clear timer 1 [sample] interrupts)
W -------x -------- (J_EXTCLR - clear external interrupts)
R/W -------- ---x---- (J_SYNENA - enable synchronous serial intf ints)
R/W -------- ----x--- (J_ASYNENA - enable asynchronous serial intf ints)
R/W -------- -----x-- (J_TIM2ENA - enable timer 2 [tempo] interrupts)
R/W -------- ------x- (J_TIM1ENA - enable timer 1 [sample] interrupts)
R/W -------- -------x (J_EXTENA - enable external interrupts)
F10030 R/W -------- xxxxxxxx ASIDATA - asynchronous serial data
F10032 W -x------ -xxxxxxx ASICTRL - asynchronous serial control
W -x------ -------- (TXBRK - transmit break)
W -------- -x------ (CLRERR - clear error)
W -------- --x----- (RINTEN - enable receiver interrupts)
W -------- ---x---- (TINTEN - enable transmitter interrupts)
W -------- ----x--- (RXIPOL - receiver input polarity)
W -------- -----x-- (TXOPOL - transmitter output polarity)
W -------- ------x- (PAREN - parity enable)
W -------- -------x (ODD - odd parity select)
F10032 R xxx-xxxx x-xxxxxx ASISTAT - asynchronous serial status
R x------- -------- (ERROR - OR of PE,FE,OE)
R -x------ -------- (TXBRK - transmit break)
R --x----- -------- (SERIN - serial input)
R ----x--- -------- (OE - overrun error)
R -----x-- -------- (FE - framing error)
R ------x- -------- (PE - parity error)
R -------x -------- (TBE - transmit buffer empty)
R -------- x------- (RBF - receive buffer full)
R -------- ---x---- (TINTEN - enable transmitter interrupts)
R -------- ----x--- (RXIPOL - receiver input polarity)
R -------- -----x-- (TXOPOL - transmitter output polarity)
R -------- ------x- (PAREN - parity enable)
R -------- -------x (ODD - odd parity)
F10034 R/W xxxxxxxx xxxxxxxx ASICLK - asynchronous serial interface clock
------------------------------------------------------------
F14000-F17FFF R/W xxxxxxxx xxxxxxxx Joysticks and GPIO0-5
F14000 R xxxxxxxx xxxxxxxx JOYSTICK - read joystick state
F14000 W x------- xxxxxxxx JOYSTICK - latch joystick output
W x------- -------- (enable joystick outputs)
W -------- xxxxxxxx (joystick output data)
F14002 R xxxxxxxx xxxxxxxx JOYBUTS - button register
F14800-F14FFF R/W xxxxxxxx xxxxxxxx GPI00 - reserved
F15000-F15FFF R/W xxxxxxxx xxxxxxxx GPI01 - reserved
F16000-F16FFF R/W xxxxxxxx xxxxxxxx GPI02 - reserved
F17000-F177FF R/W xxxxxxxx xxxxxxxx GPI03 - reserved
F17800-F17BFF R/W xxxxxxxx xxxxxxxx GPI04 - reserved
F17C00-F17FFF R/W xxxxxxxx xxxxxxxx GPI05 - reserved
------------------------------------------------------------
F18000-F1FFFF R/W xxxxxxxx xxxxxxxx Jerry DSP
F1A100 R/W xxxxxxxx xxxxxxxx D_FLAGS - DSP flags register
R/W x------- -------- (DMAEN - DMA enable)
R/W -x------ -------- (REGPAGE - register page)
W --x----- -------- (D_EXT0CLR - clear external interrupt 0)
W ---x---- -------- (D_TIM2CLR - clear timer 2 interrupt)
W ----x--- -------- (D_TIM1CLR - clear timer 1 interrupt)
W -----x-- -------- (D_I2SCLR - clear I2S interrupt)
W ------x- -------- (D_CPUCLR - clear CPU interrupt)
R/W -------x -------- (D_EXT0ENA - enable external interrupt 0)
R/W -------- x------- (D_TIM2ENA - enable timer 2 interrupt)
R/W -------- -x------ (D_TIM1ENA - enable timer 1 interrupt)
R/W -------- --x----- (D_I2SENA - enable I2S interrupt)
R/W -------- ---x---- (D_CPUENA - enable CPU interrupt)
R/W -------- ----x--- (IMASK - interrupt mask)
R/W -------- -----x-- (NEGA_FLAG - ALU negative)
R/W -------- ------x- (CARRY_FLAG - ALU carry)
R/W -------- -------x (ZERO_FLAG - ALU zero)
F1A102 R/W -------- ------xx D_FLAGS - upper DSP flags
R/W -------- ------x- (D_EXT1ENA - enable external interrupt 1)
R/W -------- -------x (D_EXT1CLR - clear external interrupt 1)
F1A104 W -------- ----xxxx D_MTXC - matrix control register
W -------- ----x--- (MATCOL - column/row major)
W -------- -----xxx (MATRIX3-15 - matrix width)
F1A108 W ----xxxx xxxxxx-- D_MTXA - matrix address register
F1A10C W -------- -----x-x D_END - data organization register
W -------- -----x-- (BIG_INST - big endian instruction fetch)
W -------- -------x (BIG_IO - big endian I/O)
F1A110 R/W xxxxxxxx xxxxxxxx D_PC - DSP program counter
F1A114 R/W xxxxxxxx xx-xxxxx D_CTRL - DSP control/status register
R xxxx---- -------- (VERSION - DSP version code)
R/W ----x--- -------- (BUS_HOG - hog the bus!)
R/W -----x-- -------- (D_EXT0LAT - external interrupt 0 latch)
R/W ------x- -------- (D_TIM2LAT - timer 2 interrupt latch)
R/W -------x -------- (D_TIM1LAT - timer 1 interrupt latch)
R/W -------- x------- (D_I2SLAT - I2S interrupt latch)
R/W -------- -x------ (D_CPULAT - CPU interrupt latch)
R/W -------- ---x---- (SINGLE_GO - single step one instruction)
R/W -------- ----x--- (SINGLE_STEP - single step mode)
R/W -------- -----x-- (FORCEINT0 - cause interrupt 0 on GPU)
R/W -------- ------x- (CPUINT - send GPU interrupt to CPU)
R/W -------- -------x (DSPGO - enable DSP execution)
F1A116 R/W -------- -------x D_CTRL - upper DSP control/status register
R/W -------- -------x (D_EXT1LAT - external interrupt 1 latch)
F1A118-F1A11B W xxxxxxxx xxxxxxxx D_MOD - modulo instruction mask
F1A11C-F1A11F R xxxxxxxx xxxxxxxx D_REMAIN - divide unit remainder
F1A11C W -------- -------x D_DIVCTRL - divide unit control
W -------- -------x (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide)
F1A120-F1A123 R xxxxxxxx xxxxxxxx D_MACHI - multiply & accumulate high bits
F1A148 W xxxxxxxx xxxxxxxx R_DAC - right transmit data
F1A14C W xxxxxxxx xxxxxxxx L_DAC - left transmit data
F1A150 W -------- xxxxxxxx SCLK - serial clock frequency
F1A150 R -------- ------xx SSTAT
R -------- ------x- (left - no description)
R -------- -------x (WS - word strobe status)
F1A154 W -------- --xxxx-x SMODE - serial mode
W -------- --x----- (EVERYWORD - interrupt on MSB of every word)
W -------- ---x---- (FALLING - interrupt on falling edge)
W -------- ----x--- (RISING - interrupt of rising edge)
W -------- -----x-- (WSEN - enable word strobes)
W -------- -------x (INTERNAL - enables serial clock)
------------------------------------------------------------
F1B000-F1CFFF R/W xxxxxxxx xxxxxxxx Local DSP RAM
------------------------------------------------------------
F1D000 R xxxxxxxx xxxxxxxx ROM_TRI - triangle wave
F1D200 R xxxxxxxx xxxxxxxx ROM_SINE - full sine wave
F1D400 R xxxxxxxx xxxxxxxx ROM_AMSINE - amplitude modulated sine wave
F1D600 R xxxxxxxx xxxxxxxx ROM_12W - sine wave and second order harmonic
F1D800 R xxxxxxxx xxxxxxxx ROM_CHIRP16 - chirp
F1DA00 R xxxxxxxx xxxxxxxx ROM_NTRI - traingle wave with noise
F1DC00 R xxxxxxxx xxxxxxxx ROM_DELTA - spike
F1DE00 R xxxxxxxx xxxxxxxx ROM_NOISE - white noise
------------------------------------------------------------
F20000-FFFFFF R xxxxxxxx xxxxxxxx Bootstrap ROM
****************************************************************************/
#include "driver.h"
#include "deprecat.h"
#include "memconv.h"
#include "includes/jaguar.h"
#include "cpu/jaguar/jaguar.h"
#include "sound/dac.h"
/* Jerry registers */
enum
{
JPIT1, DSP0, JPIT2, DSP1,
JPIT3, DSP2, JPIT4, DSP3,
CLK1, CLK2, CLK3,
JINTCTRL = 0x20/2,
ASIDATA = 0x30/2, ASICTRL, ASICLK,
DSP_REGS
};
/* DSP variables */
static UINT16 dsp_regs[DSP_REGS];
static UINT16 serial_frequency;
static emu_timer *serial_timer;
static UINT8 gpu_irq_state;
#if ENABLE_SPEEDUP_HACKS
static TIMER_CALLBACK( serial_chunky_callback );
static WRITE32_HANDLER( dsp_flags_w );
#else
static TIMER_CALLBACK( serial_callback );
#endif
/*************************************
*
* DSP optimization control
*
*************************************/
void jaguar_dsp_suspend(void)
{
cpunum_suspend(2, SUSPEND_REASON_SPIN, 1);
}
void jaguar_dsp_resume(void)
{
cpunum_resume(2, SUSPEND_REASON_SPIN);
}
/*************************************
*
* Jerry -> GPU interrupts
*
*************************************/
static void update_gpu_irq(void)
{
if (gpu_irq_state & dsp_regs[JINTCTRL] & 0x1f)
{
cpunum_set_input_line(Machine, 1, 1, ASSERT_LINE);
jaguar_gpu_resume();
}
else
cpunum_set_input_line(Machine, 1, 1, CLEAR_LINE);
}
void jaguar_external_int(int state)
{
if (state != CLEAR_LINE)
gpu_irq_state |= 1;
else
gpu_irq_state &= ~1;
update_gpu_irq();
}
/*************************************
*
* Sound initialization
*
*************************************/
void cojag_sound_init(void)
{
int i;
/* fill the wave ROM -- these are pretty cheesy guesses */
for (i = 0; i < 0x80; i++)
{
/* F1D000 = triangle wave */
jaguar_wave_rom[0x000 + i] = ((i <= 0x40) ? i : 0x80 - i) * 32767 / 0x40;
/* F1D200 = full sine wave */
jaguar_wave_rom[0x080 + i] = (int)(32767. * sin(2.0 * M_PI * (double)i / (double)0x80));
/* F1D400 = amplitude modulated sine wave? */
jaguar_wave_rom[0x100 + i] = (int)(32767. * sin(2.0 * M_PI * (double)i / (double)0x80));
/* F1D600 = sine wave and second order harmonic */
jaguar_wave_rom[0x180 + i] = (int)(32767. * sin(2.0 * M_PI * (double)i / (double)0x80));
/* F1D800 = chirp (sine wave of increasing frequency) */
jaguar_wave_rom[0x200 + i] = (int)(32767. * sin(2.0 * M_PI * (double)i / (double)0x80));
/* F1DA00 = traingle wave with noise */
jaguar_wave_rom[0x280 + i] = jaguar_wave_rom[0x000 + i] * (mame_rand(Machine) % 32768) / 32768;
/* F1DC00 = spike */
jaguar_wave_rom[0x300 + i] = (i == 0x40) ? 32767 : 0;
/* F1DE00 = white noise */
jaguar_wave_rom[0x380 + i] = mame_rand(Machine) % 32768;
}
#if ENABLE_SPEEDUP_HACKS
memory_install_write32_handler(2, ADDRESS_SPACE_PROGRAM, 0xf1a100, 0xf1a103, 0, 0, dsp_flags_w);
#endif
}
/*************************************
*
* Sound reset
*
*************************************/
void cojag_sound_reset(void)
{
#if ENABLE_SPEEDUP_HACKS
serial_timer = timer_alloc(serial_chunky_callback, NULL);
#else
serial_timer = timer_alloc(serial_callback, NULL);
#endif
}
/*************************************
*
* Jerry 16-bit register access
*
*************************************/
READ16_HANDLER( jaguar_jerry_regs_r )
{
if (offset != JINTCTRL && offset != JINTCTRL+2)
logerror("%08X:jerry read register @ F10%03X\n", activecpu_get_previouspc(), offset * 2);
switch (offset)
{
case JINTCTRL:
return gpu_irq_state;
}
return dsp_regs[offset];
}
WRITE16_HANDLER( jaguar_jerry_regs_w )
{
COMBINE_DATA(&dsp_regs[offset]);
switch (offset)
{
case JINTCTRL:
gpu_irq_state &= ~(dsp_regs[JINTCTRL] >> 8);
update_gpu_irq();
break;
}
if (offset != JINTCTRL && offset != JINTCTRL+2 && offset != ASICTRL)
logerror("%08X:jerry write register @ F10%03X = %04X\n", activecpu_get_previouspc(), offset * 2, data);
}
/*************************************
*
* Jerry 32-bit register access
*
*************************************/
READ32_HANDLER( jaguar_jerry_regs32_r )
{
return read32be_with_16be_handler(jaguar_jerry_regs_r, machine, offset, mem_mask);
}
WRITE32_HANDLER( jaguar_jerry_regs32_w )
{
write32be_with_16be_handler(jaguar_jerry_regs_w, machine, offset, data, mem_mask);
}
/*************************************
*
* Speedier sound hack
*
*************************************/
#if ENABLE_SPEEDUP_HACKS
static WRITE32_HANDLER( dsp_flags_w )
{
/* write the data through */
jaguardsp_ctrl_w(2, offset, data, mem_mask);
/* if they were clearing the A2S interrupt, see if we are headed for the spin */
/* loop with R22 != 0; if we are, just start spinning again */
if (cpu_getactivecpu() == 2 && ACCESSING_BITS_8_15 && (data & 0x400))
{
/* see if we're going back to the spin loop */
if (!(data & 0x04000) && activecpu_get_reg(JAGUAR_R22) != 0)
{
UINT32 r30 = activecpu_get_reg(JAGUAR_R30) & 0xffffff;
if (r30 >= 0xf1b124 && r30 <= 0xf1b126)
jaguar_dsp_suspend();
}
}
}
#endif
/*************************************
*
* Serial port interrupt generation
*
*************************************/
#if ENABLE_SPEEDUP_HACKS
static TIMER_CALLBACK( serial_chunky_callback )
{
/* assert the A2S IRQ on CPU #2 (DSP) */
cpunum_set_input_line(machine, 2, 1, ASSERT_LINE);
jaguar_dsp_resume();
/* fix flaky code in interrupt handler which thwarts our speedup */
if ((jaguar_dsp_ram[0x3e/4] & 0xffff) == 0xbfbc &&
(jaguar_dsp_ram[0x42/4] & 0xffff) == 0xe400)
{
/* move the store r28,(r29) into the branch delay slot, swapping it with */
/* the nop that's currently there */
jaguar_dsp_ram[0x3e/4] = (jaguar_dsp_ram[0x3e/4] & 0xffff0000) | 0xe400;
jaguar_dsp_ram[0x42/4] = (jaguar_dsp_ram[0x42/4] & 0xffff0000) | 0xbfbc;
}
}
#else
static TIMER_CALLBACK( serial_callback )
{
/* assert the A2S IRQ on CPU #2 (DSP) */
cpunum_set_input_line(machine, 2, 1, ASSERT_LINE);
jaguar_dsp_resume();
}
#endif
/*************************************
*
* Serial port handlers
*
*************************************/
READ32_HANDLER( jaguar_serial_r )
{
logerror("%08X:jaguar_serial_r(%X)\n", activecpu_get_previouspc(), offset);
return 0;
}
WRITE32_HANDLER( jaguar_serial_w )
{
switch (offset)
{
/* right DAC */
case 2:
DAC_signed_data_16_w(1, (data & 0xffff) ^ 0x8000);
break;
/* left DAC */
case 3:
DAC_signed_data_16_w(0, (data & 0xffff) ^ 0x8000);
break;
/* frequency register */
case 4:
serial_frequency = data & 0xffff;
break;
/* control register -- only very specific modes supported */
case 5:
if ((data & 0x3f) != 0x15)
logerror("Unexpected write to SMODE = %X\n", data);
if ((data & 0x3f) == 0x15)
{
attotime rate = attotime_mul(ATTOTIME_IN_HZ(26000000), 32 * 2 * (serial_frequency + 1));
timer_adjust_periodic(serial_timer, rate, 0, rate);
}
break;
default:
logerror("%08X:jaguar_serial_w(%X,%X)\n", activecpu_get_previouspc(), offset, data);
break;
}
}
|