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