]> Shamusworld >> Repos - virtualjaguar/blob - src/jerry.cpp
This commit was generated by cvs2svn to compensate for changes in r8,
[virtualjaguar] / src / jerry.cpp
1 //
2 // JERRY Core
3 //
4 // by cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups by James L. Hammons
7 //
8 //      ------------------------------------------------------------
9 //      JERRY REGISTERS (Mapped by Aaron Giles)
10 //      ------------------------------------------------------------
11 //      F10000-F13FFF   R/W   xxxxxxxx xxxxxxxx   Jerry
12 //      F10000            W   xxxxxxxx xxxxxxxx   JPIT1 - timer 1 pre-scaler
13 //      F10004            W   xxxxxxxx xxxxxxxx   JPIT2 - timer 1 divider
14 //      F10008            W   xxxxxxxx xxxxxxxx   JPIT3 - timer 2 pre-scaler
15 //      F1000C            W   xxxxxxxx xxxxxxxx   JPIT4 - timer 2 divider
16 //      F10010            W   ------xx xxxxxxxx   CLK1 - processor clock divider
17 //      F10012            W   ------xx xxxxxxxx   CLK2 - video clock divider
18 //      F10014            W   -------- --xxxxxx   CLK3 - chroma clock divider
19 //      F10020          R/W   ---xxxxx ---xxxxx   JINTCTRL - interrupt control register
20 //                        W   ---x---- --------      (J_SYNCLR - clear synchronous serial intf ints)
21 //                        W   ----x--- --------      (J_ASYNCLR - clear asynchronous serial intf ints)
22 //                        W   -----x-- --------      (J_TIM2CLR - clear timer 2 [tempo] interrupts)
23 //                        W   ------x- --------      (J_TIM1CLR - clear timer 1 [sample] interrupts)
24 //                        W   -------x --------      (J_EXTCLR - clear external interrupts)
25 //                      R/W   -------- ---x----      (J_SYNENA - enable synchronous serial intf ints)
26 //                      R/W   -------- ----x---      (J_ASYNENA - enable asynchronous serial intf ints)
27 //                      R/W   -------- -----x--      (J_TIM2ENA - enable timer 2 [tempo] interrupts)
28 //                      R/W   -------- ------x-      (J_TIM1ENA - enable timer 1 [sample] interrupts)
29 //                      R/W   -------- -------x      (J_EXTENA - enable external interrupts)
30 //      F10030          R/W   -------- xxxxxxxx   ASIDATA - asynchronous serial data
31 //      F10032            W   -x------ -xxxxxxx   ASICTRL - asynchronous serial control
32 //                        W   -x------ --------      (TXBRK - transmit break)
33 //                        W   -------- -x------      (CLRERR - clear error)
34 //                        W   -------- --x-----      (RINTEN - enable receiver interrupts)
35 //                        W   -------- ---x----      (TINTEN - enable transmitter interrupts)
36 //                        W   -------- ----x---      (RXIPOL - receiver input polarity)
37 //                        W   -------- -----x--      (TXOPOL - transmitter output polarity)
38 //                        W   -------- ------x-      (PAREN - parity enable)
39 //                        W   -------- -------x      (ODD - odd parity select)
40 //      F10032          R     xxx-xxxx x-xxxxxx   ASISTAT - asynchronous serial status
41 //                      R     x------- --------      (ERROR - OR of PE,FE,OE)
42 //                      R     -x------ --------      (TXBRK - transmit break)
43 //                      R     --x----- --------      (SERIN - serial input)
44 //                      R     ----x--- --------      (OE - overrun error)
45 //                      R     -----x-- --------      (FE - framing error)
46 //                      R     ------x- --------      (PE - parity error)
47 //                      R     -------x --------      (TBE - transmit buffer empty)
48 //                      R     -------- x-------      (RBF - receive buffer full)
49 //                      R     -------- ---x----      (TINTEN - enable transmitter interrupts)
50 //                      R     -------- ----x---      (RXIPOL - receiver input polarity)
51 //                      R     -------- -----x--      (TXOPOL - transmitter output polarity)
52 //                      R     -------- ------x-      (PAREN - parity enable)
53 //                      R     -------- -------x      (ODD - odd parity)
54 //      F10034          R/W   xxxxxxxx xxxxxxxx   ASICLK - asynchronous serial interface clock
55 //      ------------------------------------------------------------
56 //      F14000-F17FFF   R/W   xxxxxxxx xxxxxxxx   Joysticks and GPIO0-5
57 //      F14000          R     xxxxxxxx xxxxxxxx   JOYSTICK - read joystick state
58 //      F14000            W   x------- xxxxxxxx   JOYSTICK - latch joystick output
59 //                        W   x------- --------      (enable joystick outputs)
60 //                        W   -------- xxxxxxxx      (joystick output data)
61 //      F14002          R     xxxxxxxx xxxxxxxx   JOYBUTS - button register
62 //      F14800-F14FFF   R/W   xxxxxxxx xxxxxxxx   GPI00 - reserved
63 //      F15000-F15FFF   R/W   xxxxxxxx xxxxxxxx   GPI01 - reserved
64 //      F16000-F16FFF   R/W   xxxxxxxx xxxxxxxx   GPI02 - reserved
65 //      F17000-F177FF   R/W   xxxxxxxx xxxxxxxx   GPI03 - reserved
66 //      F17800-F17BFF   R/W   xxxxxxxx xxxxxxxx   GPI04 - reserved
67 //      F17C00-F17FFF   R/W   xxxxxxxx xxxxxxxx   GPI05 - reserved
68 //      ------------------------------------------------------------
69 //      F18000-F1FFFF   R/W   xxxxxxxx xxxxxxxx   Jerry DSP
70 //      F1A100          R/W   xxxxxxxx xxxxxxxx   D_FLAGS - DSP flags register
71 //                      R/W   x------- --------      (DMAEN - DMA enable)
72 //                      R/W   -x------ --------      (REGPAGE - register page)
73 //                        W   --x----- --------      (D_EXT0CLR - clear external interrupt 0)
74 //                        W   ---x---- --------      (D_TIM2CLR - clear timer 2 interrupt)
75 //                        W   ----x--- --------      (D_TIM1CLR - clear timer 1 interrupt)
76 //                        W   -----x-- --------      (D_I2SCLR - clear I2S interrupt)
77 //                        W   ------x- --------      (D_CPUCLR - clear CPU interrupt)
78 //                      R/W   -------x --------      (D_EXT0ENA - enable external interrupt 0)
79 //                      R/W   -------- x-------      (D_TIM2ENA - enable timer 2 interrupt)
80 //                      R/W   -------- -x------      (D_TIM1ENA - enable timer 1 interrupt)
81 //                      R/W   -------- --x-----      (D_I2SENA - enable I2S interrupt)
82 //                      R/W   -------- ---x----      (D_CPUENA - enable CPU interrupt)
83 //                      R/W   -------- ----x---      (IMASK - interrupt mask)
84 //                      R/W   -------- -----x--      (NEGA_FLAG - ALU negative)
85 //                      R/W   -------- ------x-      (CARRY_FLAG - ALU carry)
86 //                      R/W   -------- -------x      (ZERO_FLAG - ALU zero)
87 //      F1A102          R/W   -------- ------xx   D_FLAGS - upper DSP flags
88 //                      R/W   -------- ------x-      (D_EXT1ENA - enable external interrupt 1)
89 //                      R/W   -------- -------x      (D_EXT1CLR - clear external interrupt 1)
90 //      F1A104            W   -------- ----xxxx   D_MTXC - matrix control register
91 //                        W   -------- ----x---      (MATCOL - column/row major)
92 //                        W   -------- -----xxx      (MATRIX3-15 - matrix width)
93 //      F1A108            W   ----xxxx xxxxxx--   D_MTXA - matrix address register
94 //      F1A10C            W   -------- -----x-x   D_END - data organization register
95 //                        W   -------- -----x--      (BIG_INST - big endian instruction fetch)
96 //                        W   -------- -------x      (BIG_IO - big endian I/O)
97 //      F1A110          R/W   xxxxxxxx xxxxxxxx   D_PC - DSP program counter
98 //      F1A114          R/W   xxxxxxxx xx-xxxxx   D_CTRL - DSP control/status register
99 //                      R     xxxx---- --------      (VERSION - DSP version code)
100 //                      R/W   ----x--- --------      (BUS_HOG - hog the bus!)
101 //                      R/W   -----x-- --------      (D_EXT0LAT - external interrupt 0 latch)
102 //                      R/W   ------x- --------      (D_TIM2LAT - timer 2 interrupt latch)
103 //                      R/W   -------x --------      (D_TIM1LAT - timer 1 interrupt latch)
104 //                      R/W   -------- x-------      (D_I2SLAT - I2S interrupt latch)
105 //                      R/W   -------- -x------      (D_CPULAT - CPU interrupt latch)
106 //                      R/W   -------- ---x----      (SINGLE_GO - single step one instruction)
107 //                      R/W   -------- ----x---      (SINGLE_STEP - single step mode)
108 //                      R/W   -------- -----x--      (FORCEINT0 - cause interrupt 0 on GPU)
109 //                      R/W   -------- ------x-      (CPUINT - send GPU interrupt to CPU)
110 //                      R/W   -------- -------x      (DSPGO - enable DSP execution)
111 //      F1A116          R/W   -------- -------x   D_CTRL - upper DSP control/status register
112 //                      R/W   -------- -------x      (D_EXT1LAT - external interrupt 1 latch)
113 //      F1A118-F1A11B     W   xxxxxxxx xxxxxxxx   D_MOD - modulo instruction mask
114 //      F1A11C-F1A11F   R     xxxxxxxx xxxxxxxx   D_REMAIN - divide unit remainder
115 //      F1A11C            W   -------- -------x   D_DIVCTRL - divide unit control
116 //                        W   -------- -------x      (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide)
117 //      F1A120-F1A123   R     xxxxxxxx xxxxxxxx   D_MACHI - multiply & accumulate high bits
118 //      F1A148            W   xxxxxxxx xxxxxxxx   R_DAC - right transmit data
119 //      F1A14C            W   xxxxxxxx xxxxxxxx   L_DAC - left transmit data
120 //      F1A150            W   -------- xxxxxxxx   SCLK - serial clock frequency
121 //      F1A150          R     -------- ------xx   SSTAT
122 //                      R     -------- ------x-      (left - no description)
123 //                      R     -------- -------x      (WS - word strobe status)
124 //      F1A154            W   -------- --xxxx-x   SMODE - serial mode
125 //                        W   -------- --x-----      (EVERYWORD - interrupt on MSB of every word)
126 //                        W   -------- ---x----      (FALLING - interrupt on falling edge)
127 //                        W   -------- ----x---      (RISING - interrupt of rising edge)
128 //                        W   -------- -----x--      (WSEN - enable word strobes)
129 //                        W   -------- -------x      (INTERNAL - enables serial clock)
130 //      ------------------------------------------------------------
131 //      F1B000-F1CFFF   R/W   xxxxxxxx xxxxxxxx   Local DSP RAM
132 //      ------------------------------------------------------------
133 //      F1D000          R     xxxxxxxx xxxxxxxx   ROM_TRI - triangle wave
134 //      F1D200          R     xxxxxxxx xxxxxxxx   ROM_SINE - full sine wave
135 //      F1D400          R     xxxxxxxx xxxxxxxx   ROM_AMSINE - amplitude modulated sine wave
136 //      F1D600          R     xxxxxxxx xxxxxxxx   ROM_12W - sine wave and second order harmonic
137 //      F1D800          R     xxxxxxxx xxxxxxxx   ROM_CHIRP16 - chirp
138 //      F1DA00          R     xxxxxxxx xxxxxxxx   ROM_NTRI - traingle wave with noise
139 //      F1DC00          R     xxxxxxxx xxxxxxxx   ROM_DELTA - spike
140 //      F1DE00          R     xxxxxxxx xxxxxxxx   ROM_NOISE - white noise
141 //      ------------------------------------------------------------
142
143 #include "jerry.h"
144 #include "wavetable.h"
145 #include <math.h>
146
147 //#define JERRY_DEBUG
148
149 static uint8 * jerry_ram_8;
150 //static uint16 *jerry_ram_16;
151 //static uint8 * jerry_wave_rom;
152
153
154 //#define JERRY_CONFIG jerry_ram_16[0x4002>>1]
155 #define JERRY_CONFIG    0x4002
156
157 uint8 analog_x, analog_y;
158
159 static uint32 jerry_timer_1_prescaler;
160 static uint32 jerry_timer_2_prescaler;
161 static uint32 jerry_timer_1_divider;
162 static uint32 jerry_timer_2_divider;
163 static int32 jerry_timer_1_counter;
164 static int32 jerry_timer_2_counter;
165
166 static uint32 jerry_i2s_interrupt_divide = 8;
167 static int32  jerry_i2s_interrupt_timer = -1;
168 static int32  jerry_i2s_interrupt_cycles_per_scanline = 0;
169
170
171 void jerry_i2s_exec(uint32 cycles)
172 {       
173         jerry_i2s_interrupt_divide &= 0xFF;
174
175         if (jerry_i2s_interrupt_timer == -1)
176         {
177                 uint32 jerry_i2s_int_freq = (26591000 / 64) / (jerry_i2s_interrupt_divide + 1);
178                 jerry_i2s_interrupt_cycles_per_scanline = 13300000 / jerry_i2s_int_freq;
179                 jerry_i2s_interrupt_timer = jerry_i2s_interrupt_cycles_per_scanline;
180                 //fprintf(log_get(),"jerry: i2s interrupt rate set to %i hz (every %i cpu clock cycles) jerry_i2s_interrupt_divide=%i\n",jerry_i2s_int_freq,jerry_i2s_interrupt_cycles_per_scanline,jerry_i2s_interrupt_divide);
181                 pcm_set_sample_rate(jerry_i2s_int_freq);
182         }
183         jerry_i2s_interrupt_timer -= cycles;
184         // note : commented since the sound doesn't work properly else
185         if (1)//jerry_i2s_interrupt_timer<=0)
186         {
187                 // i2s interrupt
188                 dsp_check_if_i2s_interrupt_needed();
189                 //fprintf(log_get(),"jerry_i2s_interrupt_timer=%i, generating an i2s interrupt\n",jerry_i2s_interrupt_timer);
190                 jerry_i2s_interrupt_timer += jerry_i2s_interrupt_cycles_per_scanline;
191         }
192 }
193
194 void jerry_reset_i2s_timer(void)
195 {
196         //fprintf(log_get(),"i2s: reseting\n");
197         jerry_i2s_interrupt_divide = 8;
198         jerry_i2s_interrupt_timer = -1;
199 }
200
201 void jerry_reset_timer_1(void)
202 {
203         if (!jerry_timer_1_prescaler || !jerry_timer_1_divider)
204                 jerry_timer_1_counter = 0;
205         else
206                 jerry_timer_1_counter = (1 + jerry_timer_1_prescaler) * (1 + jerry_timer_1_divider);
207
208 //      if (jerry_timer_1_counter)
209 //              fprintf(log_get(),"jerry: reseting timer 1 to 0x%.8x (%i)\n",jerry_timer_1_counter,jerry_timer_1_counter);
210 }
211
212 void jerry_reset_timer_2(void)
213 {
214         if (!jerry_timer_2_prescaler || !jerry_timer_2_divider)
215         {
216                 jerry_timer_2_counter = 0;
217                 return;
218         }
219         else
220                 jerry_timer_2_counter = ((1 + jerry_timer_2_prescaler) * (1 + jerry_timer_2_divider));
221
222 //      if (jerry_timer_2_counter)
223 //              fprintf(log_get(),"jerry: reseting timer 2 to 0x%.8x (%i)\n",jerry_timer_2_counter,jerry_timer_2_counter);
224 }
225
226 void jerry_pit_exec(uint32 cycles)
227 {
228         if (jerry_timer_1_counter)
229                 jerry_timer_1_counter -= cycles;
230
231         if (jerry_timer_1_counter <= 0)
232         {
233                 dsp_set_irq_line(2, 1);
234                 jerry_reset_timer_1();
235         }
236
237         if (jerry_timer_2_counter)
238                 jerry_timer_2_counter -= cycles;
239
240         if (jerry_timer_2_counter <= 0)
241         {
242                 dsp_set_irq_line(3, 1);
243                 jerry_reset_timer_2();
244         }
245 }
246
247 void jerry_wave_rom_init(void)
248 {
249 //      memory_malloc_secure((void **)&jerry_wave_rom, 0x1000, "jerry wave rom");
250 //      uint32 * jaguar_wave_rom_32 = (uint32 *)jerry_wave_rom;
251
252         // use real wave table dump
253 // JLH: Looks like this WT dump is in the wrong endian (For the Jaguar, that is)...
254 //      memcpy(jerry_wave_rom, wave_table, 0x1000);
255
256         // reverse byte ordering
257 // JLH: Actually, this does nothing...
258 /*      for(int i=0; i<0x400; i++)
259         {
260                 uint32 data = jaguar_wave_rom_32[i];
261                 data = ((data & 0xFF000000) >> 24) | ((data & 0x0000FF00) << 8)
262                         | ((data & 0x00FF0000) >> 8) | ((data & 0x000000FF) << 24);
263         }*/
264 // Why the need for an extra buffer to hold it, when it already exists in the form of wave_table???
265 // Also, there was a memory leak, since it was never deallocated... (jerry_wave_rom)
266         
267         // Copy it to DSP RAM
268 //WAS:  memcpy(&jerry_ram_8[0xD000], jerry_wave_rom, 0x1000);
269         memcpy(&jerry_ram_8[0xD000], wave_table, 0x1000);
270 }
271
272 void jerry_init(void)
273 {
274         //fprintf(log_get(),"jerry_init()\n");
275         clock_init();
276         anajoy_init();
277         joystick_init();
278         eeprom_init();
279         memory_malloc_secure((void **)&jerry_ram_8, 0x10000, "jerry ram");
280 //      jerry_ram_16 = (uint16 *)jerry_ram_8;
281         jerry_wave_rom_init();
282 }
283
284 void jerry_reset(void)
285 {
286         //fprintf(log_get(),"jerry_reset()\n");
287         clock_reset();
288         anajoy_reset();
289         joystick_reset();
290         eeprom_reset();
291         jerry_reset_i2s_timer();
292
293         memset(jerry_ram_8, 0x00, 0x10000);
294         jerry_ram_8[JERRY_CONFIG+1] |= 0x10; // NTSC (bit 4)
295         jerry_timer_1_prescaler = 0xFFFF;
296         jerry_timer_2_prescaler = 0xFFFF;
297         jerry_timer_1_divider = 0xFFFF;
298         jerry_timer_2_divider = 0xFFFF;
299         jerry_timer_1_counter = 0;
300         jerry_timer_2_counter = 0;
301
302 }
303
304 void jerry_done(void)
305 {
306         //fprintf(log_get(),"jerry_done()\n");
307         memory_free(jerry_ram_8);
308         clock_done();
309         anajoy_done();
310         joystick_done();
311         eeprom_done();
312 }
313
314 //
315 // JERRY byte access (read)
316 //
317
318 unsigned jerry_byte_read(unsigned int offset)
319 {
320 #ifdef JERRY_DEBUG
321         fprintf(log_get(),"jerry: reading byte at 0x%.6x\n",offset);
322 #endif
323         if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
324                 return dsp_byte_read(offset);
325         else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
326                 return dsp_byte_read(offset);
327         else if ((offset >= 0xF10000) && (offset <= 0xF10007))
328         {
329                 switch(offset & 0x07)
330                 {
331                 case 0:
332                         return jerry_timer_1_prescaler >> 8;
333                 case 1:
334                         return jerry_timer_1_prescaler & 0xFF;
335                 case 2:
336                         return jerry_timer_1_divider >> 8;
337                 case 3:
338                         return jerry_timer_1_divider & 0xFF;
339                 case 4:
340                         return jerry_timer_2_prescaler >> 8;
341                 case 5:
342                         return jerry_timer_2_prescaler & 0xFF;
343                 case 6:
344                         return jerry_timer_2_divider >> 8;
345                 case 7:
346                         return jerry_timer_2_divider & 0xFF;
347                 }
348         }
349         else if ((offset >= 0xF10010) && (offset <= 0xf10015))
350                 return clock_byte_read(offset);
351         else if ((offset >= 0xF17C00) && (offset <= 0xF17C01))
352                 return anajoy_byte_read(offset);
353         else if ((offset >= 0xF14000) && (offset <= 0xF14003))
354         {
355                 return joystick_byte_read(offset) | eeprom_byte_read(offset);
356         }
357         else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF))
358                 return eeprom_byte_read(offset);
359         
360         return jerry_ram_8[offset & 0xFFFF];
361 }
362
363 //
364 // JERRY word access (read)
365 //
366
367 unsigned jerry_word_read(unsigned int offset)
368 {
369 #ifdef JERRY_DEBUG
370         fprintf(log_get(),"jerry: reading word at 0x%.6x\n",offset);
371 #endif
372
373         if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
374                 return dsp_word_read(offset);
375         else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
376                 return dsp_word_read(offset);
377         else if ((offset >= 0xF10000) && (offset <= 0xF10007))
378         {
379                 switch(offset & 0x07)
380                 {
381                 case 0:
382                         return jerry_timer_1_prescaler;
383                 case 2:
384                         return jerry_timer_1_divider;
385                 case 4:
386                         return jerry_timer_2_prescaler;
387                 case 6:
388                         return jerry_timer_2_divider;
389                 }
390                 // Unaligned word reads???
391         }
392         else if ((offset >= 0xF10010) && (offset <= 0xF10015))
393                 return clock_word_read(offset);
394         else if (offset == 0xF10020)
395                 return 0x00;
396         else if ((offset >= 0xF17C00) && (offset <= 0xF17C01))
397                 return anajoy_word_read(offset);
398         else if (offset == 0xF14000)
399         {
400                 //fprintf(log_get(),"reading 0x%.4x from 0xf14000\n");
401                 return (joystick_word_read(offset) & 0xFFFE) | eeprom_word_read(offset);
402         }
403         else if ((offset >= 0xF14002) && (offset < 0xF14003))
404                 return joystick_word_read(offset);
405         else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF))
406                 return eeprom_word_read(offset);
407
408 // This is never executed!
409 /*      offset &= 0xFFFF;
410         if (offset==0x4002)
411                 return(0xffff);*/
412
413 /*      uint16 data = jerry_ram_8[offset+0];
414         data <<= 8;
415         data |= jerry_ram_8[offset+1];
416         return data;*/
417         return ((uint16)jerry_ram_8[offset+0] << 8) | jerry_ram_8[offset+1];
418 }
419
420 //
421 // JERRY byte access (write)
422 //
423
424 void jerry_byte_write(unsigned offset, unsigned data)
425 {
426 #ifdef JERRY_DEBUG
427         fprintf(log_get(),"jerry: writing byte %.2x at 0x%.6x\n",data,offset);
428 #endif
429         if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
430         {
431                 dsp_byte_write(offset, data);
432                 return;
433         }
434         else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
435         {
436                 dsp_byte_write(offset, data);
437                 return;
438         }
439         else if ((offset >= 0xF1A152) && (offset <= 0xF1A153))
440         {
441 //              fprintf(log_get(),"i2s: writing 0x%.2x to SCLK\n",data);
442                 if ((offset & 0x03) == 2)
443                         jerry_i2s_interrupt_divide = (jerry_i2s_interrupt_divide & 0x00FF) | ((uint32)data << 8);
444                 else
445                         jerry_i2s_interrupt_divide = (jerry_i2s_interrupt_divide & 0xFF00) | (uint32)data;
446
447                 jerry_i2s_interrupt_timer = -1;
448                 jerry_i2s_exec(0);
449                 return;
450         }
451         else if ((offset >= 0xF10000) && (offset <= 0xF10007))
452         {
453                 switch(offset & 0x07)
454                 {
455                 case 0:
456                         jerry_timer_1_prescaler = (jerry_timer_1_prescaler & 0x00FF) | (data << 8);
457                         jerry_reset_timer_1();
458                         break;
459                 case 1: { jerry_timer_1_prescaler=(jerry_timer_1_prescaler&0xff00)|(data);              jerry_reset_timer_1(); return; }
460                 case 2: { jerry_timer_1_divider=(jerry_timer_1_divider&0x00ff)|(data<<8);               jerry_reset_timer_1(); return; }
461                 case 3: { jerry_timer_1_divider=(jerry_timer_1_divider&0xff00)|(data);                  jerry_reset_timer_1(); return; }
462                 case 4: { jerry_timer_2_prescaler=(jerry_timer_2_prescaler&0x00ff)|(data<<8);   jerry_reset_timer_2(); return; }
463                 case 5: { jerry_timer_2_prescaler=(jerry_timer_2_prescaler&0xff00)|(data);              jerry_reset_timer_2(); return; }
464                 case 6: { jerry_timer_2_divider=(jerry_timer_2_divider&0x00ff)|(data<<8);               jerry_reset_timer_2(); return; }
465                 case 7: { jerry_timer_2_divider=(jerry_timer_2_divider&0xff00)|(data);                  jerry_reset_timer_2(); return; }
466                 }
467                 return;
468         }
469         else if ((offset >= 0xF10010) && (offset <= 0xF10015))
470         {
471                 clock_byte_write(offset, data);
472                 return;
473         }
474         else if ((offset >= 0xF17C00) && (offset <= 0xF17C01))
475         {
476                 anajoy_byte_write(offset, data);
477                 return;
478         }
479         else if ((offset >= 0xF14000) && (offset <= 0xF14003))
480         {
481                 joystick_byte_write(offset, data);
482                 eeprom_byte_write(offset, data);
483                 return;
484         }
485         else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF))
486         {
487                 eeprom_byte_write(offset, data);
488                 return;
489         }
490
491         jerry_ram_8[offset & 0xFFFF] = data;
492 }
493
494 //
495 // JERRY word access (write)
496 //
497
498 void jerry_word_write(unsigned offset, unsigned data)
499 {
500 #ifdef JERRY_DEBUG
501         fprintf(log_get(), "JERRY: Writing word %04X at %06X\n", data, offset);
502 #endif
503
504         if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
505         {
506                 dsp_word_write(offset, data);
507                 return;
508         }
509         else if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
510         {
511                 dsp_word_write(offset, data);
512                 return;
513         }
514         else if (offset == 0xF1A152)
515         {
516 //              fprintf(log_get(),"i2s: writing 0x%.4x to SCLK\n",data);
517                 jerry_i2s_interrupt_divide = data & 0xFF;
518                 jerry_i2s_interrupt_timer = -1;
519                 jerry_i2s_exec(0);
520         }
521         else if ((offset >= 0xF10000) && (offset <= 0xF10007))
522         {
523                 switch(offset & 0x07)
524                 {
525                 case 0:
526                         jerry_timer_1_prescaler = data;
527                         jerry_reset_timer_1();
528                         break;
529                 case 2:
530                         jerry_timer_1_divider = data;
531                         jerry_reset_timer_1();
532                         break;
533                 case 4:
534                         jerry_timer_2_prescaler = data;
535                         jerry_reset_timer_2();
536                         break;
537                 case 6:
538                         jerry_timer_2_divider = data;
539                         jerry_reset_timer_2();
540                 }
541                 // Need to handle (unaligned) cases???
542                 return;
543         }
544         else if ((offset >= 0xF1A148) && (offset < 0xF1A150)) 
545         { 
546                 pcm_word_write(offset - 0xF1A148, data); 
547                 return; 
548         }
549         else if ((offset >= 0xF10010) && (offset < 0xF10016))
550         {
551                 clock_word_write(offset, data);
552                 return;
553         }
554         else if ((offset >= 0xF17C00) && (offset < 0xF17C02))
555         {
556                 anajoy_word_write(offset, data);
557                 return;
558         }
559         else if ((offset >= 0xF14000) && (offset < 0xF14003))
560         {
561                 joystick_word_write(offset, data);
562                 eeprom_word_write(offset, data);
563                 return;
564         }
565         else if ((offset >= 0xF14000) && (offset <= 0xF1A0FF))
566         {
567                 eeprom_word_write(offset, data);
568                 return;
569         }
570
571         jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF;
572         jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF;
573 }