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