Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / memory / memory.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - memory.c                                                *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2002 Hacktarux                                          *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include <stdlib.h>
23
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <errno.h>
27
28 #if !defined(WIN32)
29 #include <sys/mman.h>
30 #endif
31
32 #include "api/m64p_types.h"
33
34 #include "memory.h"
35 #include "dma.h"
36 #include "pif.h"
37 #include "flashram.h"
38
39 #include "r4300/r4300.h"
40 #include "r4300/macros.h"
41 #include "r4300/interupt.h"
42 #include "r4300/recomph.h"
43 #include "r4300/ops.h"
44
45 #include "api/callbacks.h"
46 #include "main/main.h"
47 #include "main/rom.h"
48 #include "osal/preproc.h"
49 #include "plugin/plugin.h"
50 #include "r4300/new_dynarec/new_dynarec.h"
51
52 #ifdef DBG
53 #include "debugger/dbg_types.h"
54 #include "debugger/dbg_memory.h"
55 #include "debugger/dbg_breakpoints.h"
56 #endif
57
58 /* definitions of the rcp's structures and memory area */
59 RDRAM_register rdram_register;
60 mips_register MI_register;
61 PI_register pi_register;
62 SP_register sp_register;
63 RSP_register rsp_register;
64 SI_register si_register;
65 VI_register vi_register;
66 RI_register ri_register;
67 AI_register ai_register;
68 DPC_register dpc_register;
69 DPS_register dps_register;
70
71 ALIGN(16, unsigned int rdram[0x800000/4]);
72
73 unsigned char *rdramb = (unsigned char *)(rdram);
74 unsigned int SP_DMEM[0x1000/4*2];
75 unsigned int *SP_IMEM = SP_DMEM+0x1000/4;
76 unsigned char *SP_DMEMb = (unsigned char *)(SP_DMEM);
77 unsigned char *SP_IMEMb = (unsigned char*)(SP_DMEM+0x1000/4);
78 unsigned int PIF_RAM[0x40/4];
79 unsigned char *PIF_RAMb = (unsigned char *)(PIF_RAM);
80
81 #if NEW_DYNAREC != NEW_DYNAREC_ARM
82 // address : address of the read/write operation being done
83 unsigned int address = 0;
84 #endif
85 // *address_low = the lower 16 bit of the address :
86 #ifdef M64P_BIG_ENDIAN
87 static unsigned short *address_low = (unsigned short *)(&address)+1;
88 #else
89 static unsigned short *address_low = (unsigned short *)(&address);
90 #endif
91
92 // values that are being written are stored in these variables
93 #if NEW_DYNAREC != NEW_DYNAREC_ARM
94 unsigned int word;
95 unsigned char cpu_byte;
96 unsigned short hword;
97 unsigned long long int dword;
98 #endif
99
100 // addresse where the read value will be stored
101 unsigned long long int* rdword;
102
103 // trash : when we write to unmaped memory it is written here
104 static unsigned int trash;
105
106 // hash tables of read functions
107 void (*readmem[0x10000])(void);
108 void (*readmemb[0x10000])(void);
109 void (*readmemh[0x10000])(void);
110 void (*readmemd[0x10000])(void);
111
112 // hash tables of write functions
113 void (*writemem[0x10000])(void);
114 void (*writememb[0x10000])(void);
115 void (*writememd[0x10000])(void);
116 void (*writememh[0x10000])(void);
117
118 // memory sections
119 unsigned int *readrdramreg[0x10000];
120 unsigned int *readrspreg[0x10000];
121 unsigned int *readrsp[0x10000];
122 unsigned int *readmi[0x10000];
123 unsigned int *readvi[0x10000];
124 unsigned int *readai[0x10000];
125 unsigned int *readpi[0x10000];
126 unsigned int *readri[0x10000];
127 unsigned int *readsi[0x10000];
128 unsigned int *readdp[0x10000];
129 unsigned int *readdps[0x10000];
130
131 // the frameBufferInfos
132 static FrameBufferInfo frameBufferInfos[6];
133 static char framebufferRead[0x800];
134 static int firstFrameBufferSetting;
135
136 // uncomment to output count of calls to write_rdram():
137 //#define COUNT_WRITE_RDRAM_CALLS 1
138
139 #if defined( COUNT_WRITE_RDRAM_CALLS )
140         int writerdram_count = 1;
141 #endif
142
143 int init_memory(int DoByteSwap)
144 {
145     int i;
146
147     if (DoByteSwap != 0)
148     {
149         //swap rom
150         unsigned int *roml = (unsigned int *) rom;
151         for (i=0; i<(rom_size/4); i++) roml[i] = sl(roml[i]);
152     }
153
154     //init hash tables
155     for (i=0; i<(0x10000); i++)
156     {
157         readmem[i] = read_nomem;
158         readmemb[i] = read_nomemb;
159         readmemd[i] = read_nomemd;
160         readmemh[i] = read_nomemh;
161         writemem[i] = write_nomem;
162         writememb[i] = write_nomemb;
163         writememd[i] = write_nomemd;
164         writememh[i] = write_nomemh;
165     }
166
167     //init RDRAM
168     for (i=0; i<(0x800000/4); i++) rdram[i]=0;
169
170     for (i=0; i</*0x40*/0x80; i++)
171     {
172         readmem[(0x8000+i)] = read_rdram;
173         readmem[(0xa000+i)] = read_rdram;
174         readmemb[(0x8000+i)] = read_rdramb;
175         readmemb[(0xa000+i)] = read_rdramb;
176         readmemh[(0x8000+i)] = read_rdramh;
177         readmemh[(0xa000+i)] = read_rdramh;
178         readmemd[(0x8000+i)] = read_rdramd;
179         readmemd[(0xa000+i)] = read_rdramd;
180         writemem[(0x8000+i)] = write_rdram;
181         writemem[(0xa000+i)] = write_rdram;
182         writememb[(0x8000+i)] = write_rdramb;
183         writememb[(0xa000+i)] = write_rdramb;
184         writememh[(0x8000+i)] = write_rdramh;
185         writememh[(0xa000+i)] = write_rdramh;
186         writememd[(0x8000+i)] = write_rdramd;
187         writememd[(0xa000+i)] = write_rdramd;
188     }
189
190     for (i=/*0x40*/0x80; i<0x3F0; i++)
191     {
192         readmem[0x8000+i] = read_nothing;
193         readmem[0xa000+i] = read_nothing;
194         readmemb[0x8000+i] = read_nothingb;
195         readmemb[0xa000+i] = read_nothingb;
196         readmemh[0x8000+i] = read_nothingh;
197         readmemh[0xa000+i] = read_nothingh;
198         readmemd[0x8000+i] = read_nothingd;
199         readmemd[0xa000+i] = read_nothingd;
200         writemem[0x8000+i] = write_nothing;
201         writemem[0xa000+i] = write_nothing;
202         writememb[0x8000+i] = write_nothingb;
203         writememb[0xa000+i] = write_nothingb;
204         writememh[0x8000+i] = write_nothingh;
205         writememh[0xa000+i] = write_nothingh;
206         writememd[0x8000+i] = write_nothingd;
207         writememd[0xa000+i] = write_nothingd;
208     }
209
210     //init RDRAM registers
211     readmem[0x83f0] = read_rdramreg;
212     readmem[0xa3f0] = read_rdramreg;
213     readmemb[0x83f0] = read_rdramregb;
214     readmemb[0xa3f0] = read_rdramregb;
215     readmemh[0x83f0] = read_rdramregh;
216     readmemh[0xa3f0] = read_rdramregh;
217     readmemd[0x83f0] = read_rdramregd;
218     readmemd[0xa3f0] = read_rdramregd;
219     writemem[0x83f0] = write_rdramreg;
220     writemem[0xa3f0] = write_rdramreg;
221     writememb[0x83f0] = write_rdramregb;
222     writememb[0xa3f0] = write_rdramregb;
223     writememh[0x83f0] = write_rdramregh;
224     writememh[0xa3f0] = write_rdramregh;
225     writememd[0x83f0] = write_rdramregd;
226     writememd[0xa3f0] = write_rdramregd;
227     rdram_register.rdram_config=0;
228     rdram_register.rdram_device_id=0;
229     rdram_register.rdram_delay=0;
230     rdram_register.rdram_mode=0;
231     rdram_register.rdram_ref_interval=0;
232     rdram_register.rdram_ref_row=0;
233     rdram_register.rdram_ras_interval=0;
234     rdram_register.rdram_min_interval=0;
235     rdram_register.rdram_addr_select=0;
236     rdram_register.rdram_device_manuf=0;
237     readrdramreg[0x0] = &rdram_register.rdram_config;
238     readrdramreg[0x4] = &rdram_register.rdram_device_id;
239     readrdramreg[0x8] = &rdram_register.rdram_delay;
240     readrdramreg[0xc] = &rdram_register.rdram_mode;
241     readrdramreg[0x10] = &rdram_register.rdram_ref_interval;
242     readrdramreg[0x14] = &rdram_register.rdram_ref_row;
243     readrdramreg[0x18] = &rdram_register.rdram_ras_interval;
244     readrdramreg[0x1c] = &rdram_register.rdram_min_interval;
245     readrdramreg[0x20] = &rdram_register.rdram_addr_select;
246     readrdramreg[0x24] = &rdram_register.rdram_device_manuf;
247
248     for (i=0x28; i<0x10000; i++) readrdramreg[i] = &trash;
249     for (i=1; i<0x10; i++)
250     {
251         readmem[0x83f0+i] = read_nothing;
252         readmem[0xa3f0+i] = read_nothing;
253         readmemb[0x83f0+i] = read_nothingb;
254         readmemb[0xa3f0+i] = read_nothingb;
255         readmemh[0x83f0+i] = read_nothingh;
256         readmemh[0xa3f0+i] = read_nothingh;
257         readmemd[0x83f0+i] = read_nothingd;
258         readmemd[0xa3f0+i] = read_nothingd;
259         writemem[0x83f0+i] = write_nothing;
260         writemem[0xa3f0+i] = write_nothing;
261         writememb[0x83f0+i] = write_nothingb;
262         writememb[0xa3f0+i] = write_nothingb;
263         writememh[0x83f0+i] = write_nothingh;
264         writememh[0xa3f0+i] = write_nothingh;
265         writememd[0x83f0+i] = write_nothingd;
266         writememd[0xa3f0+i] = write_nothingd;
267     }
268
269     //init RSP memory
270     readmem[0x8400] = read_rsp_mem;
271     readmem[0xa400] = read_rsp_mem;
272     readmemb[0x8400] = read_rsp_memb;
273     readmemb[0xa400] = read_rsp_memb;
274     readmemh[0x8400] = read_rsp_memh;
275     readmemh[0xa400] = read_rsp_memh;
276     readmemd[0x8400] = read_rsp_memd;
277     readmemd[0xa400] = read_rsp_memd;
278     writemem[0x8400] = write_rsp_mem;
279     writemem[0xa400] = write_rsp_mem;
280     writememb[0x8400] = write_rsp_memb;
281     writememb[0xa400] = write_rsp_memb;
282     writememh[0x8400] = write_rsp_memh;
283     writememh[0xa400] = write_rsp_memh;
284     writememd[0x8400] = write_rsp_memd;
285     writememd[0xa400] = write_rsp_memd;
286     for (i=0; i<(0x1000/4); i++) SP_DMEM[i]=0;
287     for (i=0; i<(0x1000/4); i++) SP_IMEM[i]=0;
288
289     for (i=1; i<0x4; i++)
290     {
291         readmem[0x8400+i] = read_nothing;
292         readmem[0xa400+i] = read_nothing;
293         readmemb[0x8400+i] = read_nothingb;
294         readmemb[0xa400+i] = read_nothingb;
295         readmemh[0x8400+i] = read_nothingh;
296         readmemh[0xa400+i] = read_nothingh;
297         readmemd[0x8400+i] = read_nothingd;
298         readmemd[0xa400+i] = read_nothingd;
299         writemem[0x8400+i] = write_nothing;
300         writemem[0xa400+i] = write_nothing;
301         writememb[0x8400+i] = write_nothingb;
302         writememb[0xa400+i] = write_nothingb;
303         writememh[0x8400+i] = write_nothingh;
304         writememh[0xa400+i] = write_nothingh;
305         writememd[0x8400+i] = write_nothingd;
306         writememd[0xa400+i] = write_nothingd;
307     }
308
309     //init RSP registers
310     readmem[0x8404] = read_rsp_reg;
311     readmem[0xa404] = read_rsp_reg;
312     readmemb[0x8404] = read_rsp_regb;
313     readmemb[0xa404] = read_rsp_regb;
314     readmemh[0x8404] = read_rsp_regh;
315     readmemh[0xa404] = read_rsp_regh;
316     readmemd[0x8404] = read_rsp_regd;
317     readmemd[0xa404] = read_rsp_regd;
318     writemem[0x8404] = write_rsp_reg;
319     writemem[0xa404] = write_rsp_reg;
320     writememb[0x8404] = write_rsp_regb;
321     writememb[0xa404] = write_rsp_regb;
322     writememh[0x8404] = write_rsp_regh;
323     writememh[0xa404] = write_rsp_regh;
324     writememd[0x8404] = write_rsp_regd;
325     writememd[0xa404] = write_rsp_regd;
326     sp_register.sp_mem_addr_reg=0;
327     sp_register.sp_dram_addr_reg=0;
328     sp_register.sp_rd_len_reg=0;
329     sp_register.sp_wr_len_reg=0;
330     sp_register.sp_status_reg=1;
331     sp_register.w_sp_status_reg=0;
332     sp_register.sp_dma_full_reg=0;
333     sp_register.sp_dma_busy_reg=0;
334     sp_register.sp_semaphore_reg=0;
335     readrspreg[0x0] = &sp_register.sp_mem_addr_reg;
336     readrspreg[0x4] = &sp_register.sp_dram_addr_reg;
337     readrspreg[0x8] = &sp_register.sp_rd_len_reg;
338     readrspreg[0xc] = &sp_register.sp_wr_len_reg;
339     readrspreg[0x10] = &sp_register.sp_status_reg;
340     readrspreg[0x14] = &sp_register.sp_dma_full_reg;
341     readrspreg[0x18] = &sp_register.sp_dma_busy_reg;
342     readrspreg[0x1c] = &sp_register.sp_semaphore_reg;
343
344     for (i=0x20; i<0x10000; i++) readrspreg[i] = &trash;
345     for (i=5; i<8; i++)
346     {
347         readmem[0x8400+i] = read_nothing;
348         readmem[0xa400+i] = read_nothing;
349         readmemb[0x8400+i] = read_nothingb;
350         readmemb[0xa400+i] = read_nothingb;
351         readmemh[0x8400+i] = read_nothingh;
352         readmemh[0xa400+i] = read_nothingh;
353         readmemd[0x8400+i] = read_nothingd;
354         readmemd[0xa400+i] = read_nothingd;
355         writemem[0x8400+i] = write_nothing;
356         writemem[0xa400+i] = write_nothing;
357         writememb[0x8400+i] = write_nothingb;
358         writememb[0xa400+i] = write_nothingb;
359         writememh[0x8400+i] = write_nothingh;
360         writememh[0xa400+i] = write_nothingh;
361         writememd[0x8400+i] = write_nothingd;
362         writememd[0xa400+i] = write_nothingd;
363     }
364
365     readmem[0x8408] = read_rsp;
366     readmem[0xa408] = read_rsp;
367     readmemb[0x8408] = read_rspb;
368     readmemb[0xa408] = read_rspb;
369     readmemh[0x8408] = read_rsph;
370     readmemh[0xa408] = read_rsph;
371     readmemd[0x8408] = read_rspd;
372     readmemd[0xa408] = read_rspd;
373     writemem[0x8408] = write_rsp;
374     writemem[0xa408] = write_rsp;
375     writememb[0x8408] = write_rspb;
376     writememb[0xa408] = write_rspb;
377     writememh[0x8408] = write_rsph;
378     writememh[0xa408] = write_rsph;
379     writememd[0x8408] = write_rspd;
380     writememd[0xa408] = write_rspd;
381     rsp_register.rsp_pc=0;
382     rsp_register.rsp_ibist=0;
383     readrsp[0x0] = &rsp_register.rsp_pc;
384     readrsp[0x4] = &rsp_register.rsp_ibist;
385
386     for (i=0x8; i<0x10000; i++) readrsp[i] = &trash;
387     for (i=9; i<0x10; i++)
388     {
389         readmem[0x8400+i] = read_nothing;
390         readmem[0xa400+i] = read_nothing;
391         readmemb[0x8400+i] = read_nothingb;
392         readmemb[0xa400+i] = read_nothingb;
393         readmemh[0x8400+i] = read_nothingh;
394         readmemh[0xa400+i] = read_nothingh;
395         readmemd[0x8400+i] = read_nothingd;
396         readmemd[0xa400+i] = read_nothingd;
397         writemem[0x8400+i] = write_nothing;
398         writemem[0xa400+i] = write_nothing;
399         writememb[0x8400+i] = write_nothingb;
400         writememb[0xa400+i] = write_nothingb;
401         writememh[0x8400+i] = write_nothingh;
402         writememh[0xa400+i] = write_nothingh;
403         writememd[0x8400+i] = write_nothingd;
404         writememd[0xa400+i] = write_nothingd;
405     }
406
407     //init rdp command registers
408     readmem[0x8410] = read_dp;
409     readmem[0xa410] = read_dp;
410     readmemb[0x8410] = read_dpb;
411     readmemb[0xa410] = read_dpb;
412     readmemh[0x8410] = read_dph;
413     readmemh[0xa410] = read_dph;
414     readmemd[0x8410] = read_dpd;
415     readmemd[0xa410] = read_dpd;
416     writemem[0x8410] = write_dp;
417     writemem[0xa410] = write_dp;
418     writememb[0x8410] = write_dpb;
419     writememb[0xa410] = write_dpb;
420     writememh[0x8410] = write_dph;
421     writememh[0xa410] = write_dph;
422     writememd[0x8410] = write_dpd;
423     writememd[0xa410] = write_dpd;
424     dpc_register.dpc_start=0;
425     dpc_register.dpc_end=0;
426     dpc_register.dpc_current=0;
427     dpc_register.w_dpc_status=0;
428     dpc_register.dpc_status=0;
429     dpc_register.dpc_clock=0;
430     dpc_register.dpc_bufbusy=0;
431     dpc_register.dpc_pipebusy=0;
432     dpc_register.dpc_tmem=0;
433     readdp[0x0] = &dpc_register.dpc_start;
434     readdp[0x4] = &dpc_register.dpc_end;
435     readdp[0x8] = &dpc_register.dpc_current;
436     readdp[0xc] = &dpc_register.dpc_status;
437     readdp[0x10] = &dpc_register.dpc_clock;
438     readdp[0x14] = &dpc_register.dpc_bufbusy;
439     readdp[0x18] = &dpc_register.dpc_pipebusy;
440     readdp[0x1c] = &dpc_register.dpc_tmem;
441
442     for (i=0x20; i<0x10000; i++) readdp[i] = &trash;
443     for (i=1; i<0x10; i++)
444     {
445         readmem[0x8410+i] = read_nothing;
446         readmem[0xa410+i] = read_nothing;
447         readmemb[0x8410+i] = read_nothingb;
448         readmemb[0xa410+i] = read_nothingb;
449         readmemh[0x8410+i] = read_nothingh;
450         readmemh[0xa410+i] = read_nothingh;
451         readmemd[0x8410+i] = read_nothingd;
452         readmemd[0xa410+i] = read_nothingd;
453         writemem[0x8410+i] = write_nothing;
454         writemem[0xa410+i] = write_nothing;
455         writememb[0x8410+i] = write_nothingb;
456         writememb[0xa410+i] = write_nothingb;
457         writememh[0x8410+i] = write_nothingh;
458         writememh[0xa410+i] = write_nothingh;
459         writememd[0x8410+i] = write_nothingd;
460         writememd[0xa410+i] = write_nothingd;
461     }
462
463     //init rsp span registers
464     readmem[0x8420] = read_dps;
465     readmem[0xa420] = read_dps;
466     readmemb[0x8420] = read_dpsb;
467     readmemb[0xa420] = read_dpsb;
468     readmemh[0x8420] = read_dpsh;
469     readmemh[0xa420] = read_dpsh;
470     readmemd[0x8420] = read_dpsd;
471     readmemd[0xa420] = read_dpsd;
472     writemem[0x8420] = write_dps;
473     writemem[0xa420] = write_dps;
474     writememb[0x8420] = write_dpsb;
475     writememb[0xa420] = write_dpsb;
476     writememh[0x8420] = write_dpsh;
477     writememh[0xa420] = write_dpsh;
478     writememd[0x8420] = write_dpsd;
479     writememd[0xa420] = write_dpsd;
480     dps_register.dps_tbist=0;
481     dps_register.dps_test_mode=0;
482     dps_register.dps_buftest_addr=0;
483     dps_register.dps_buftest_data=0;
484     readdps[0x0] = &dps_register.dps_tbist;
485     readdps[0x4] = &dps_register.dps_test_mode;
486     readdps[0x8] = &dps_register.dps_buftest_addr;
487     readdps[0xc] = &dps_register.dps_buftest_data;
488
489     for (i=0x10; i<0x10000; i++) readdps[i] = &trash;
490     for (i=1; i<0x10; i++)
491     {
492         readmem[0x8420+i] = read_nothing;
493         readmem[0xa420+i] = read_nothing;
494         readmemb[0x8420+i] = read_nothingb;
495         readmemb[0xa420+i] = read_nothingb;
496         readmemh[0x8420+i] = read_nothingh;
497         readmemh[0xa420+i] = read_nothingh;
498         readmemd[0x8420+i] = read_nothingd;
499         readmemd[0xa420+i] = read_nothingd;
500         writemem[0x8420+i] = write_nothing;
501         writemem[0xa420+i] = write_nothing;
502         writememb[0x8420+i] = write_nothingb;
503         writememb[0xa420+i] = write_nothingb;
504         writememh[0x8420+i] = write_nothingh;
505         writememh[0xa420+i] = write_nothingh;
506         writememd[0x8420+i] = write_nothingd;
507         writememd[0xa420+i] = write_nothingd;
508     }
509
510     //init mips registers
511     readmem[0xa830] = read_mi;
512     readmem[0xa430] = read_mi;
513     readmemb[0xa830] = read_mib;
514     readmemb[0xa430] = read_mib;
515     readmemh[0xa830] = read_mih;
516     readmemh[0xa430] = read_mih;
517     readmemd[0xa830] = read_mid;
518     readmemd[0xa430] = read_mid;
519     writemem[0x8430] = write_mi;
520     writemem[0xa430] = write_mi;
521     writememb[0x8430] = write_mib;
522     writememb[0xa430] = write_mib;
523     writememh[0x8430] = write_mih;
524     writememh[0xa430] = write_mih;
525     writememd[0x8430] = write_mid;
526     writememd[0xa430] = write_mid;
527     MI_register.w_mi_init_mode_reg = 0;
528     MI_register.mi_init_mode_reg = 0;
529     MI_register.mi_version_reg = 0x02020102;
530     MI_register.mi_intr_reg = 0;
531     MI_register.w_mi_intr_mask_reg = 0;
532     MI_register.mi_intr_mask_reg = 0;
533     readmi[0x0] = &MI_register.mi_init_mode_reg;
534     readmi[0x4] = &MI_register.mi_version_reg;
535     readmi[0x8] = &MI_register.mi_intr_reg;
536     readmi[0xc] = &MI_register.mi_intr_mask_reg;
537
538     for (i=0x10; i<0x10000; i++) readmi[i] = &trash;
539     for (i=1; i<0x10; i++)
540     {
541         readmem[0x8430+i] = read_nothing;
542         readmem[0xa430+i] = read_nothing;
543         readmemb[0x8430+i] = read_nothingb;
544         readmemb[0xa430+i] = read_nothingb;
545         readmemh[0x8430+i] = read_nothingh;
546         readmemh[0xa430+i] = read_nothingh;
547         readmemd[0x8430+i] = read_nothingd;
548         readmemd[0xa430+i] = read_nothingd;
549         writemem[0x8430+i] = write_nothing;
550         writemem[0xa430+i] = write_nothing;
551         writememb[0x8430+i] = write_nothingb;
552         writememb[0xa430+i] = write_nothingb;
553         writememh[0x8430+i] = write_nothingh;
554         writememh[0xa430+i] = write_nothingh;
555         writememd[0x8430+i] = write_nothingd;
556         writememd[0xa430+i] = write_nothingd;
557     }
558
559     //init VI registers
560     readmem[0x8440] = read_vi;
561     readmem[0xa440] = read_vi;
562     readmemb[0x8440] = read_vib;
563     readmemb[0xa440] = read_vib;
564     readmemh[0x8440] = read_vih;
565     readmemh[0xa440] = read_vih;
566     readmemd[0x8440] = read_vid;
567     readmemd[0xa440] = read_vid;
568     writemem[0x8440] = write_vi;
569     writemem[0xa440] = write_vi;
570     writememb[0x8440] = write_vib;
571     writememb[0xa440] = write_vib;
572     writememh[0x8440] = write_vih;
573     writememh[0xa440] = write_vih;
574     writememd[0x8440] = write_vid;
575     writememd[0xa440] = write_vid;
576     vi_register.vi_status = 0;
577     vi_register.vi_origin = 0;
578     vi_register.vi_width = 0;
579     vi_register.vi_v_intr = 0;
580     vi_register.vi_current = 0;
581     vi_register.vi_burst = 0;
582     vi_register.vi_v_sync = 0;
583     vi_register.vi_h_sync = 0;
584     vi_register.vi_leap = 0;
585     vi_register.vi_h_start = 0;
586     vi_register.vi_v_start = 0;
587     vi_register.vi_v_burst = 0;
588     vi_register.vi_x_scale = 0;
589     vi_register.vi_y_scale = 0;
590     readvi[0x0] = &vi_register.vi_status;
591     readvi[0x4] = &vi_register.vi_origin;
592     readvi[0x8] = &vi_register.vi_width;
593     readvi[0xc] = &vi_register.vi_v_intr;
594     readvi[0x10] = &vi_register.vi_current;
595     readvi[0x14] = &vi_register.vi_burst;
596     readvi[0x18] = &vi_register.vi_v_sync;
597     readvi[0x1c] = &vi_register.vi_h_sync;
598     readvi[0x20] = &vi_register.vi_leap;
599     readvi[0x24] = &vi_register.vi_h_start;
600     readvi[0x28] = &vi_register.vi_v_start;
601     readvi[0x2c] = &vi_register.vi_v_burst;
602     readvi[0x30] = &vi_register.vi_x_scale;
603     readvi[0x34] = &vi_register.vi_y_scale;
604
605     for (i=0x38; i<0x10000; i++) readvi[i] = &trash;
606     for (i=1; i<0x10; i++)
607     {
608         readmem[0x8440+i] = read_nothing;
609         readmem[0xa440+i] = read_nothing;
610         readmemb[0x8440+i] = read_nothingb;
611         readmemb[0xa440+i] = read_nothingb;
612         readmemh[0x8440+i] = read_nothingh;
613         readmemh[0xa440+i] = read_nothingh;
614         readmemd[0x8440+i] = read_nothingd;
615         readmemd[0xa440+i] = read_nothingd;
616         writemem[0x8440+i] = write_nothing;
617         writemem[0xa440+i] = write_nothing;
618         writememb[0x8440+i] = write_nothingb;
619         writememb[0xa440+i] = write_nothingb;
620         writememh[0x8440+i] = write_nothingh;
621         writememh[0xa440+i] = write_nothingh;
622         writememd[0x8440+i] = write_nothingd;
623         writememd[0xa440+i] = write_nothingd;
624     }
625
626     //init AI registers
627     readmem[0x8450] = read_ai;
628     readmem[0xa450] = read_ai;
629     readmemb[0x8450] = read_aib;
630     readmemb[0xa450] = read_aib;
631     readmemh[0x8450] = read_aih;
632     readmemh[0xa450] = read_aih;
633     readmemd[0x8450] = read_aid;
634     readmemd[0xa450] = read_aid;
635     writemem[0x8450] = write_ai;
636     writemem[0xa450] = write_ai;
637     writememb[0x8450] = write_aib;
638     writememb[0xa450] = write_aib;
639     writememh[0x8450] = write_aih;
640     writememh[0xa450] = write_aih;
641     writememd[0x8450] = write_aid;
642     writememd[0xa450] = write_aid;
643     ai_register.ai_dram_addr = 0;
644     ai_register.ai_len = 0;
645     ai_register.ai_control = 0;
646     ai_register.ai_status = 0;
647     ai_register.ai_dacrate = 0;
648     ai_register.ai_bitrate = 0;
649     ai_register.next_delay = 0;
650     ai_register.next_len = 0;
651     ai_register.current_delay = 0;
652     ai_register.current_len = 0;
653     readai[0x0] = &ai_register.ai_dram_addr;
654     readai[0x4] = &ai_register.ai_len;
655     readai[0x8] = &ai_register.ai_control;
656     readai[0xc] = &ai_register.ai_status;
657     readai[0x10] = &ai_register.ai_dacrate;
658     readai[0x14] = &ai_register.ai_bitrate;
659
660     for (i=0x18; i<0x10000; i++) readai[i] = &trash;
661     for (i=1; i<0x10; i++)
662     {
663         readmem[0x8450+i] = read_nothing;
664         readmem[0xa450+i] = read_nothing;
665         readmemb[0x8450+i] = read_nothingb;
666         readmemb[0xa450+i] = read_nothingb;
667         readmemh[0x8450+i] = read_nothingh;
668         readmemh[0xa450+i] = read_nothingh;
669         readmemd[0x8450+i] = read_nothingd;
670         readmemd[0xa450+i] = read_nothingd;
671         writemem[0x8450+i] = write_nothing;
672         writemem[0xa450+i] = write_nothing;
673         writememb[0x8450+i] = write_nothingb;
674         writememb[0xa450+i] = write_nothingb;
675         writememh[0x8450+i] = write_nothingh;
676         writememh[0xa450+i] = write_nothingh;
677         writememd[0x8450+i] = write_nothingd;
678         writememd[0xa450+i] = write_nothingd;
679     }
680
681     //init PI registers
682     readmem[0x8460] = read_pi;
683     readmem[0xa460] = read_pi;
684     readmemb[0x8460] = read_pib;
685     readmemb[0xa460] = read_pib;
686     readmemh[0x8460] = read_pih;
687     readmemh[0xa460] = read_pih;
688     readmemd[0x8460] = read_pid;
689     readmemd[0xa460] = read_pid;
690     writemem[0x8460] = write_pi;
691     writemem[0xa460] = write_pi;
692     writememb[0x8460] = write_pib;
693     writememb[0xa460] = write_pib;
694     writememh[0x8460] = write_pih;
695     writememh[0xa460] = write_pih;
696     writememd[0x8460] = write_pid;
697     writememd[0xa460] = write_pid;
698     pi_register.pi_dram_addr_reg = 0;
699     pi_register.pi_cart_addr_reg = 0;
700     pi_register.pi_rd_len_reg = 0;
701     pi_register.pi_wr_len_reg = 0;
702     pi_register.read_pi_status_reg = 0;
703     pi_register.pi_bsd_dom1_lat_reg = 0;
704     pi_register.pi_bsd_dom1_pwd_reg = 0;
705     pi_register.pi_bsd_dom1_pgs_reg = 0;
706     pi_register.pi_bsd_dom1_rls_reg = 0;
707     pi_register.pi_bsd_dom2_lat_reg = 0;
708     pi_register.pi_bsd_dom2_pwd_reg = 0;
709     pi_register.pi_bsd_dom2_pgs_reg = 0;
710     pi_register.pi_bsd_dom2_rls_reg = 0;
711     readpi[0x0] = &pi_register.pi_dram_addr_reg;
712     readpi[0x4] = &pi_register.pi_cart_addr_reg;
713     readpi[0x8] = &pi_register.pi_rd_len_reg;
714     readpi[0xc] = &pi_register.pi_wr_len_reg;
715     readpi[0x10] = &pi_register.read_pi_status_reg;
716     readpi[0x14] = &pi_register.pi_bsd_dom1_lat_reg;
717     readpi[0x18] = &pi_register.pi_bsd_dom1_pwd_reg;
718     readpi[0x1c] = &pi_register.pi_bsd_dom1_pgs_reg;
719     readpi[0x20] = &pi_register.pi_bsd_dom1_rls_reg;
720     readpi[0x24] = &pi_register.pi_bsd_dom2_lat_reg;
721     readpi[0x28] = &pi_register.pi_bsd_dom2_pwd_reg;
722     readpi[0x2c] = &pi_register.pi_bsd_dom2_pgs_reg;
723     readpi[0x30] = &pi_register.pi_bsd_dom2_rls_reg;
724
725     for (i=0x34; i<0x10000; i++) readpi[i] = &trash;
726     for (i=1; i<0x10; i++)
727     {
728         readmem[0x8460+i] = read_nothing;
729         readmem[0xa460+i] = read_nothing;
730         readmemb[0x8460+i] = read_nothingb;
731         readmemb[0xa460+i] = read_nothingb;
732         readmemh[0x8460+i] = read_nothingh;
733         readmemh[0xa460+i] = read_nothingh;
734         readmemd[0x8460+i] = read_nothingd;
735         readmemd[0xa460+i] = read_nothingd;
736         writemem[0x8460+i] = write_nothing;
737         writemem[0xa460+i] = write_nothing;
738         writememb[0x8460+i] = write_nothingb;
739         writememb[0xa460+i] = write_nothingb;
740         writememh[0x8460+i] = write_nothingh;
741         writememh[0xa460+i] = write_nothingh;
742         writememd[0x8460+i] = write_nothingd;
743         writememd[0xa460+i] = write_nothingd;
744     }
745
746     //init RI registers
747     readmem[0x8470] = read_ri;
748     readmem[0xa470] = read_ri;
749     readmemb[0x8470] = read_rib;
750     readmemb[0xa470] = read_rib;
751     readmemh[0x8470] = read_rih;
752     readmemh[0xa470] = read_rih;
753     readmemd[0x8470] = read_rid;
754     readmemd[0xa470] = read_rid;
755     writemem[0x8470] = write_ri;
756     writemem[0xa470] = write_ri;
757     writememb[0x8470] = write_rib;
758     writememb[0xa470] = write_rib;
759     writememh[0x8470] = write_rih;
760     writememh[0xa470] = write_rih;
761     writememd[0x8470] = write_rid;
762     writememd[0xa470] = write_rid;
763     ri_register.ri_mode = 0;
764     ri_register.ri_config = 0;
765     ri_register.ri_select = 0;
766     ri_register.ri_current_load = 0;
767     ri_register.ri_refresh = 0;
768     ri_register.ri_latency = 0;
769     ri_register.ri_error = 0;
770     ri_register.ri_werror = 0;
771     readri[0x0] = &ri_register.ri_mode;
772     readri[0x4] = &ri_register.ri_config;
773     readri[0x8] = &ri_register.ri_current_load;
774     readri[0xc] = &ri_register.ri_select;
775     readri[0x10] = &ri_register.ri_refresh;
776     readri[0x14] = &ri_register.ri_latency;
777     readri[0x18] = &ri_register.ri_error;
778     readri[0x1c] = &ri_register.ri_werror;
779
780     for (i=0x20; i<0x10000; i++) readri[i] = &trash;
781     for (i=1; i<0x10; i++)
782     {
783         readmem[0x8470+i] = read_nothing;
784         readmem[0xa470+i] = read_nothing;
785         readmemb[0x8470+i] = read_nothingb;
786         readmemb[0xa470+i] = read_nothingb;
787         readmemh[0x8470+i] = read_nothingh;
788         readmemh[0xa470+i] = read_nothingh;
789         readmemd[0x8470+i] = read_nothingd;
790         readmemd[0xa470+i] = read_nothingd;
791         writemem[0x8470+i] = write_nothing;
792         writemem[0xa470+i] = write_nothing;
793         writememb[0x8470+i] = write_nothingb;
794         writememb[0xa470+i] = write_nothingb;
795         writememh[0x8470+i] = write_nothingh;
796         writememh[0xa470+i] = write_nothingh;
797         writememd[0x8470+i] = write_nothingd;
798         writememd[0xa470+i] = write_nothingd;
799     }
800
801     //init SI registers
802     readmem[0x8480] = read_si;
803     readmem[0xa480] = read_si;
804     readmemb[0x8480] = read_sib;
805     readmemb[0xa480] = read_sib;
806     readmemh[0x8480] = read_sih;
807     readmemh[0xa480] = read_sih;
808     readmemd[0x8480] = read_sid;
809     readmemd[0xa480] = read_sid;
810     writemem[0x8480] = write_si;
811     writemem[0xa480] = write_si;
812     writememb[0x8480] = write_sib;
813     writememb[0xa480] = write_sib;
814     writememh[0x8480] = write_sih;
815     writememh[0xa480] = write_sih;
816     writememd[0x8480] = write_sid;
817     writememd[0xa480] = write_sid;
818     si_register.si_dram_addr = 0;
819     si_register.si_pif_addr_rd64b = 0;
820     si_register.si_pif_addr_wr64b = 0;
821     si_register.si_stat = 0;
822     readsi[0x0] = &si_register.si_dram_addr;
823     readsi[0x4] = &si_register.si_pif_addr_rd64b;
824     readsi[0x8] = &trash;
825     readsi[0x10] = &si_register.si_pif_addr_wr64b;
826     readsi[0x14] = &trash;
827     readsi[0x18] = &si_register.si_stat;
828
829     for (i=0x1c; i<0x10000; i++) readsi[i] = &trash;
830     for (i=0x481; i<0x800; i++)
831     {
832         readmem[0x8000+i] = read_nothing;
833         readmem[0xa000+i] = read_nothing;
834         readmemb[0x8000+i] = read_nothingb;
835         readmemb[0xa000+i] = read_nothingb;
836         readmemh[0x8000+i] = read_nothingh;
837         readmemh[0xa000+i] = read_nothingh;
838         readmemd[0x8000+i] = read_nothingd;
839         readmemd[0xa000+i] = read_nothingd;
840         writemem[0x8000+i] = write_nothing;
841         writemem[0xa000+i] = write_nothing;
842         writememb[0x8000+i] = write_nothingb;
843         writememb[0xa000+i] = write_nothingb;
844         writememh[0x8000+i] = write_nothingh;
845         writememh[0xa000+i] = write_nothingh;
846         writememd[0x8000+i] = write_nothingd;
847         writememd[0xa000+i] = write_nothingd;
848     }
849
850     //init flashram / sram
851     readmem[0x8800] = read_flashram_status;
852     readmem[0xa800] = read_flashram_status;
853     readmemb[0x8800] = read_flashram_statusb;
854     readmemb[0xa800] = read_flashram_statusb;
855     readmemh[0x8800] = read_flashram_statush;
856     readmemh[0xa800] = read_flashram_statush;
857     readmemd[0x8800] = read_flashram_statusd;
858     readmemd[0xa800] = read_flashram_statusd;
859     writemem[0x8800] = write_flashram_dummy;
860     writemem[0xa800] = write_flashram_dummy;
861     writememb[0x8800] = write_flashram_dummyb;
862     writememb[0xa800] = write_flashram_dummyb;
863     writememh[0x8800] = write_flashram_dummyh;
864     writememh[0xa800] = write_flashram_dummyh;
865     writememd[0x8800] = write_flashram_dummyd;
866     writememd[0xa800] = write_flashram_dummyd;
867     readmem[0x8801] = read_nothing;
868     readmem[0xa801] = read_nothing;
869     readmemb[0x8801] = read_nothingb;
870     readmemb[0xa801] = read_nothingb;
871     readmemh[0x8801] = read_nothingh;
872     readmemh[0xa801] = read_nothingh;
873     readmemd[0x8801] = read_nothingd;
874     readmemd[0xa801] = read_nothingd;
875     writemem[0x8801] = write_flashram_command;
876     writemem[0xa801] = write_flashram_command;
877     writememb[0x8801] = write_flashram_commandb;
878     writememb[0xa801] = write_flashram_commandb;
879     writememh[0x8801] = write_flashram_commandh;
880     writememh[0xa801] = write_flashram_commandh;
881     writememd[0x8801] = write_flashram_commandd;
882     writememd[0xa801] = write_flashram_commandd;
883
884     for (i=0x802; i<0x1000; i++)
885     {
886         readmem[0x8000+i] = read_nothing;
887         readmem[0xa000+i] = read_nothing;
888         readmemb[0x8000+i] = read_nothingb;
889         readmemb[0xa000+i] = read_nothingb;
890         readmemh[0x8000+i] = read_nothingh;
891         readmemh[0xa000+i] = read_nothingh;
892         readmemd[0x8000+i] = read_nothingd;
893         readmemd[0xa000+i] = read_nothingd;
894         writemem[0x8000+i] = write_nothing;
895         writemem[0xa000+i] = write_nothing;
896         writememb[0x8000+i] = write_nothingb;
897         writememb[0xa000+i] = write_nothingb;
898         writememh[0x8000+i] = write_nothingh;
899         writememh[0xa000+i] = write_nothingh;
900         writememd[0x8000+i] = write_nothingd;
901         writememd[0xa000+i] = write_nothingd;
902     }
903
904     //init rom area
905     for (i=0; i<(rom_size >> 16); i++)
906     {
907         readmem[0x9000+i] = read_rom;
908         readmem[0xb000+i] = read_rom;
909         readmemb[0x9000+i] = read_romb;
910         readmemb[0xb000+i] = read_romb;
911         readmemh[0x9000+i] = read_romh;
912         readmemh[0xb000+i] = read_romh;
913         readmemd[0x9000+i] = read_romd;
914         readmemd[0xb000+i] = read_romd;
915         writemem[0x9000+i] = write_nothing;
916         writemem[0xb000+i] = write_rom;
917         writememb[0x9000+i] = write_nothingb;
918         writememb[0xb000+i] = write_nothingb;
919         writememh[0x9000+i] = write_nothingh;
920         writememh[0xb000+i] = write_nothingh;
921         writememd[0x9000+i] = write_nothingd;
922         writememd[0xb000+i] = write_nothingd;
923     }
924     for (i=(rom_size >> 16); i<0xfc0; i++)
925     {
926         readmem[0x9000+i] = read_nothing;
927         readmem[0xb000+i] = read_nothing;
928         readmemb[0x9000+i] = read_nothingb;
929         readmemb[0xb000+i] = read_nothingb;
930         readmemh[0x9000+i] = read_nothingh;
931         readmemh[0xb000+i] = read_nothingh;
932         readmemd[0x9000+i] = read_nothingd;
933         readmemd[0xb000+i] = read_nothingd;
934         writemem[0x9000+i] = write_nothing;
935         writemem[0xb000+i] = write_nothing;
936         writememb[0x9000+i] = write_nothingb;
937         writememb[0xb000+i] = write_nothingb;
938         writememh[0x9000+i] = write_nothingh;
939         writememh[0xb000+i] = write_nothingh;
940         writememd[0x9000+i] = write_nothingd;
941         writememd[0xb000+i] = write_nothingd;
942     }
943
944     //init PIF_RAM
945     readmem[0x9fc0] = read_pif;
946     readmem[0xbfc0] = read_pif;
947     readmemb[0x9fc0] = read_pifb;
948     readmemb[0xbfc0] = read_pifb;
949     readmemh[0x9fc0] = read_pifh;
950     readmemh[0xbfc0] = read_pifh;
951     readmemd[0x9fc0] = read_pifd;
952     readmemd[0xbfc0] = read_pifd;
953     writemem[0x9fc0] = write_pif;
954     writemem[0xbfc0] = write_pif;
955     writememb[0x9fc0] = write_pifb;
956     writememb[0xbfc0] = write_pifb;
957     writememh[0x9fc0] = write_pifh;
958     writememh[0xbfc0] = write_pifh;
959     writememd[0x9fc0] = write_pifd;
960     writememd[0xbfc0] = write_pifd;
961     for (i=0; i<(0x40/4); i++) PIF_RAM[i]=0;
962
963     for (i=0xfc1; i<0x1000; i++)
964     {
965         readmem[0x9000+i] = read_nothing;
966         readmem[0xb000+i] = read_nothing;
967         readmemb[0x9000+i] = read_nothingb;
968         readmemb[0xb000+i] = read_nothingb;
969         readmemh[0x9000+i] = read_nothingh;
970         readmemh[0xb000+i] = read_nothingh;
971         readmemd[0x9000+i] = read_nothingd;
972         readmemd[0xb000+i] = read_nothingd;
973         writemem[0x9000+i] = write_nothing;
974         writemem[0xb000+i] = write_nothing;
975         writememb[0x9000+i] = write_nothingb;
976         writememb[0xb000+i] = write_nothingb;
977         writememh[0x9000+i] = write_nothingh;
978         writememh[0xb000+i] = write_nothingh;
979         writememd[0x9000+i] = write_nothingd;
980         writememd[0xb000+i] = write_nothingd;
981     }
982
983     flashram_info.use_flashram = 0;
984     init_flashram();
985
986     frameBufferInfos[0].addr = 0;
987     fast_memory = 1;
988     firstFrameBufferSetting = 1;
989
990     DebugMessage(M64MSG_VERBOSE, "Memory initialized");
991     return 0;
992 }
993
994 void free_memory(void)
995 {
996 }
997
998 void make_w_mi_init_mode_reg(void)
999 {
1000     MI_register.w_mi_init_mode_reg = MI_register.mi_init_mode_reg & 0x7F;
1001     if ((MI_register.mi_init_mode_reg & 0x080) == 0)
1002         MI_register.w_mi_init_mode_reg |= 0x0000080;
1003     else
1004         MI_register.w_mi_init_mode_reg |= 0x0000100;
1005
1006     if ((MI_register.mi_init_mode_reg & 0x100) == 0)
1007         MI_register.w_mi_init_mode_reg |= 0x0000200;
1008     else
1009         MI_register.w_mi_init_mode_reg |= 0x0000400;
1010
1011     if ((MI_register.mi_init_mode_reg & 0x200) == 0)
1012         MI_register.w_mi_init_mode_reg |= 0x0001000;
1013     else
1014         MI_register.w_mi_init_mode_reg |= 0x0002000;
1015 }
1016
1017 static void update_MI_init_mode_reg(void)
1018 {
1019     MI_register.mi_init_mode_reg &= ~0x7F; // init_length
1020     MI_register.mi_init_mode_reg |= MI_register.w_mi_init_mode_reg & 0x7F;
1021
1022     if (MI_register.w_mi_init_mode_reg & 0x80) // clear init_mode
1023         MI_register.mi_init_mode_reg &= ~0x80;
1024     if (MI_register.w_mi_init_mode_reg & 0x100) // set init_mode
1025         MI_register.mi_init_mode_reg |= 0x80;
1026
1027     if (MI_register.w_mi_init_mode_reg & 0x200) // clear ebus_test_mode
1028         MI_register.mi_init_mode_reg &= ~0x100;
1029     if (MI_register.w_mi_init_mode_reg & 0x400) // set ebus_test_mode
1030         MI_register.mi_init_mode_reg |= 0x100;
1031
1032     if (MI_register.w_mi_init_mode_reg & 0x800) // clear DP interupt
1033     {
1034         MI_register.mi_intr_reg &= ~0x20;
1035         check_interupt();
1036     }
1037
1038     if (MI_register.w_mi_init_mode_reg & 0x1000) // clear RDRAM_reg_mode
1039         MI_register.mi_init_mode_reg &= ~0x200;
1040     if (MI_register.w_mi_init_mode_reg & 0x2000) // set RDRAM_reg_mode
1041         MI_register.mi_init_mode_reg |= 0x200;
1042 }
1043
1044 void make_w_mi_intr_mask_reg(void)
1045 {
1046     MI_register.w_mi_intr_mask_reg = 0;
1047     if ((MI_register.mi_intr_mask_reg & 0x01) == 0)
1048         MI_register.w_mi_intr_mask_reg |= 0x0000001;
1049     else
1050         MI_register.w_mi_intr_mask_reg |= 0x0000002;
1051     
1052     if ((MI_register.mi_intr_mask_reg & 0x02) == 0)
1053         MI_register.w_mi_intr_mask_reg |= 0x0000004;
1054     else
1055         MI_register.w_mi_intr_mask_reg |= 0x0000008;
1056     
1057     if ((MI_register.mi_intr_mask_reg & 0x04) == 0)
1058         MI_register.w_mi_intr_mask_reg |= 0x0000010;
1059     else
1060         MI_register.w_mi_intr_mask_reg |= 0x0000020;
1061     
1062     if ((MI_register.mi_intr_mask_reg & 0x08) == 0)
1063         MI_register.w_mi_intr_mask_reg |= 0x0000040;
1064     else
1065         MI_register.w_mi_intr_mask_reg |= 0x0000080;
1066     
1067     if ((MI_register.mi_intr_mask_reg & 0x10) == 0)
1068         MI_register.w_mi_intr_mask_reg |= 0x0000100;
1069     else
1070         MI_register.w_mi_intr_mask_reg |= 0x0000200;
1071     
1072     if ((MI_register.mi_intr_mask_reg & 0x20) == 0)
1073         MI_register.w_mi_intr_mask_reg |= 0x0000400;
1074     else
1075         MI_register.w_mi_intr_mask_reg |= 0x0000800;
1076 }
1077
1078 static void update_MI_intr_mask_reg(void)
1079 {
1080     if (MI_register.w_mi_intr_mask_reg & 0x1)   MI_register.mi_intr_mask_reg &= ~0x1; // clear SP mask
1081     if (MI_register.w_mi_intr_mask_reg & 0x2)   MI_register.mi_intr_mask_reg |= 0x1; // set SP mask
1082     if (MI_register.w_mi_intr_mask_reg & 0x4)   MI_register.mi_intr_mask_reg &= ~0x2; // clear SI mask
1083     if (MI_register.w_mi_intr_mask_reg & 0x8)   MI_register.mi_intr_mask_reg |= 0x2; // set SI mask
1084     if (MI_register.w_mi_intr_mask_reg & 0x10)  MI_register.mi_intr_mask_reg &= ~0x4; // clear AI mask
1085     if (MI_register.w_mi_intr_mask_reg & 0x20)  MI_register.mi_intr_mask_reg |= 0x4; // set AI mask
1086     if (MI_register.w_mi_intr_mask_reg & 0x40)  MI_register.mi_intr_mask_reg &= ~0x8; // clear VI mask
1087     if (MI_register.w_mi_intr_mask_reg & 0x80)  MI_register.mi_intr_mask_reg |= 0x8; // set VI mask
1088     if (MI_register.w_mi_intr_mask_reg & 0x100) MI_register.mi_intr_mask_reg &= ~0x10; // clear PI mask
1089     if (MI_register.w_mi_intr_mask_reg & 0x200) MI_register.mi_intr_mask_reg |= 0x10; // set PI mask
1090     if (MI_register.w_mi_intr_mask_reg & 0x400) MI_register.mi_intr_mask_reg &= ~0x20; // clear DP mask
1091     if (MI_register.w_mi_intr_mask_reg & 0x800) MI_register.mi_intr_mask_reg |= 0x20; // set DP mask
1092 }
1093
1094 void make_w_sp_status_reg(void)
1095 {
1096     sp_register.w_sp_status_reg = 0;
1097
1098     if ((sp_register.sp_status_reg & 0x0001) == 0)
1099         sp_register.w_sp_status_reg |= 0x0000001;
1100     else
1101         sp_register.w_sp_status_reg |= 0x0000002;
1102
1103     if ((sp_register.sp_status_reg & 0x0002) == 0)
1104         sp_register.w_sp_status_reg |= 0x0000004;
1105
1106     // TODO: should the interupt bits be set under any circumstance?
1107
1108     if ((sp_register.sp_status_reg & 0x0020) == 0)
1109         sp_register.w_sp_status_reg |= 0x0000020;
1110     else
1111         sp_register.w_sp_status_reg |= 0x0000040;
1112
1113     if ((sp_register.sp_status_reg & 0x0040) == 0)
1114         sp_register.w_sp_status_reg |= 0x0000080;
1115     else
1116         sp_register.w_sp_status_reg |= 0x0000100;
1117     if ((sp_register.sp_status_reg & 0x0080) == 0)
1118         sp_register.w_sp_status_reg |= 0x0000200;
1119     else
1120         sp_register.w_sp_status_reg |= 0x0000400;
1121
1122     if ((sp_register.sp_status_reg & 0x0100) == 0)
1123         sp_register.w_sp_status_reg |= 0x0000800;
1124     else
1125         sp_register.w_sp_status_reg |= 0x0001000;
1126
1127     if ((sp_register.sp_status_reg & 0x0200) == 0)
1128         sp_register.w_sp_status_reg |= 0x0002000;
1129     else
1130         sp_register.w_sp_status_reg |= 0x0004000;
1131
1132     if ((sp_register.sp_status_reg & 0x0400) == 0)
1133         sp_register.w_sp_status_reg |= 0x0008000;
1134     else
1135         sp_register.w_sp_status_reg |= 0x0010000;
1136
1137     if ((sp_register.sp_status_reg & 0x0800) == 0)
1138         sp_register.w_sp_status_reg |= 0x0020000;
1139     else
1140         sp_register.w_sp_status_reg |= 0x0040000;
1141
1142     if ((sp_register.sp_status_reg & 0x1000) == 0)
1143         sp_register.w_sp_status_reg |= 0x0080000;
1144     else
1145         sp_register.w_sp_status_reg |= 0x0100000;
1146
1147     if ((sp_register.sp_status_reg & 0x2000) == 0)
1148         sp_register.w_sp_status_reg |= 0x0200000;
1149     else
1150         sp_register.w_sp_status_reg |= 0x0400000;
1151
1152     if ((sp_register.sp_status_reg & 0x4000) == 0)
1153         sp_register.w_sp_status_reg |= 0x0800000;
1154     else
1155         sp_register.w_sp_status_reg |= 0x1000000;
1156 }
1157
1158 static void do_SP_Task(void)
1159 {
1160     int save_pc = rsp_register.rsp_pc & ~0xFFF;
1161     if (SP_DMEM[0xFC0/4] == 1)
1162     {
1163         if (dpc_register.dpc_status & 0x2) // DP frozen (DK64, BC)
1164         {
1165             // don't do the task now
1166             // the task will be done when DP is unfreezed (see update_DPC)
1167             return;
1168         }
1169         
1170         // unprotecting old frame buffers
1171         if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite &&
1172                 frameBufferInfos[0].addr)
1173         {
1174             int i;
1175             for (i=0; i<6; i++)
1176             {
1177                 if (frameBufferInfos[i].addr)
1178                 {
1179                     int j;
1180                     int start = frameBufferInfos[i].addr & 0x7FFFFF;
1181                     int end = start + frameBufferInfos[i].width*
1182                               frameBufferInfos[i].height*
1183                               frameBufferInfos[i].size - 1;
1184                     start = start >> 16;
1185                     end = end >> 16;
1186
1187                     for (j=start; j<=end; j++)
1188                     {
1189 #ifdef DBG
1190                         if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000,
1191                                               BPT_FLAG_ENABLED |  BPT_FLAG_READ ) != -1)
1192                         {
1193                             readmem[0x8000+j] = read_rdram_break;
1194                             readmemb[0x8000+j] = read_rdramb_break;
1195                             readmemh[0x8000+j] = read_rdramh_break;
1196                             readmemd[0xa000+j] = read_rdramd_break;
1197                         }
1198                         else
1199                         {
1200 #endif
1201                             readmem[0x8000+j] = read_rdram;
1202                             readmemb[0x8000+j] = read_rdramb;
1203                             readmemh[0x8000+j] = read_rdramh;
1204                             readmemd[0xa000+j] = read_rdramd;
1205 #ifdef DBG
1206                         }
1207                         if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000,
1208                                               BPT_FLAG_ENABLED |  BPT_FLAG_READ ) != -1)
1209                         {
1210                             readmem[0xa000+j] = read_rdram_break;
1211                             readmemb[0xa000+j] = read_rdramb_break;
1212                             readmemh[0xa000+j] = read_rdramh_break;
1213                             readmemd[0x8000+j] = read_rdramd_break;
1214                         }
1215                         else
1216                         {
1217 #endif
1218                             readmem[0xa000+j] = read_rdram;
1219                             readmemb[0xa000+j] = read_rdramb;
1220                             readmemh[0xa000+j] = read_rdramh;
1221                             readmemd[0x8000+j] = read_rdramd;
1222 #ifdef DBG
1223                         }
1224                         if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000,
1225                                               BPT_FLAG_ENABLED |  BPT_FLAG_WRITE ) != -1)
1226                         {
1227                             writemem[0x8000+j] = write_rdram_break;
1228                             writememb[0x8000+j] = write_rdramb_break;
1229                             writememh[0x8000+j] = write_rdramh_break;
1230                             writememd[0x8000+j] = write_rdramd_break;
1231                         }
1232                         else
1233                         {
1234 #endif
1235                             writemem[0x8000+j] = write_rdram;
1236                             writememb[0x8000+j] = write_rdramb;
1237                             writememh[0x8000+j] = write_rdramh;
1238                             writememd[0x8000+j] = write_rdramd;
1239 #ifdef DBG
1240                         }
1241                         if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000,
1242                                               BPT_FLAG_ENABLED |  BPT_FLAG_WRITE ) != -1)
1243                         {
1244                             writemem[0xa000+j] = write_rdram_break;
1245                             writememb[0xa000+j] = write_rdramb_break;
1246                             writememh[0xa000+j] = write_rdramh_break;
1247                             writememd[0xa000+j] = write_rdramd_break;
1248                         }
1249                         else
1250                         {
1251 #endif
1252                             writemem[0xa000+j] = write_rdram;
1253                             writememb[0xa000+j] = write_rdramb;
1254                             writememh[0xa000+j] = write_rdramh;
1255                             writememd[0xa000+j] = write_rdramd;
1256 #ifdef DBG
1257                         }
1258 #endif
1259                     }
1260                 }
1261             }
1262         }
1263
1264         //gfx.processDList();
1265         rsp_register.rsp_pc &= 0xFFF;
1266         start_section(GFX_SECTION);
1267         rsp.doRspCycles(0xFFFFFFFF);
1268         end_section(GFX_SECTION);
1269         rsp_register.rsp_pc |= save_pc;
1270         new_frame();
1271
1272         update_count();
1273         if (MI_register.mi_intr_reg & 0x1)
1274             add_interupt_event(SP_INT, 1000);
1275         if (MI_register.mi_intr_reg & 0x20)
1276             add_interupt_event(DP_INT, 1000);
1277         MI_register.mi_intr_reg &= ~0x21;
1278         sp_register.sp_status_reg &= ~0x303;
1279
1280         // protecting new frame buffers
1281         if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite)
1282             gfx.fBGetFrameBufferInfo(frameBufferInfos);
1283         if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite
1284                 && frameBufferInfos[0].addr)
1285         {
1286             int i;
1287             for (i=0; i<6; i++)
1288             {
1289                 if (frameBufferInfos[i].addr)
1290                 {
1291                     int j;
1292                     int start = frameBufferInfos[i].addr & 0x7FFFFF;
1293                     int end = start + frameBufferInfos[i].width*
1294                               frameBufferInfos[i].height*
1295                               frameBufferInfos[i].size - 1;
1296                     int start1 = start;
1297                     int end1 = end;
1298                     start >>= 16;
1299                     end >>= 16;
1300                     for (j=start; j<=end; j++)
1301                     {
1302 #ifdef DBG
1303                         if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000,
1304                                               BPT_FLAG_ENABLED |  BPT_FLAG_READ ) != -1)
1305                         {
1306                             readmem[0x8000+j] = read_rdramFB_break;
1307                             readmemb[0x8000+j] = read_rdramFBb_break;
1308                             readmemh[0x8000+j] = read_rdramFBh_break;
1309                             readmemd[0xa000+j] = read_rdramFBd_break;
1310                         }
1311                         else
1312                         {
1313 #endif
1314                             readmem[0x8000+j] = read_rdramFB;
1315                             readmemb[0x8000+j] = read_rdramFBb;
1316                             readmemh[0x8000+j] = read_rdramFBh;
1317                             readmemd[0xa000+j] = read_rdramFBd;
1318 #ifdef DBG
1319                         }
1320                         if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000,
1321                                               BPT_FLAG_ENABLED |  BPT_FLAG_READ ) != -1)
1322                         {
1323                             readmem[0xa000+j] = read_rdramFB_break;
1324                             readmemb[0xa000+j] = read_rdramFBb_break;
1325                             readmemh[0xa000+j] = read_rdramFBh_break;
1326                             readmemd[0x8000+j] = read_rdramFBd_break;
1327                         }
1328                         else
1329                         {
1330 #endif
1331                             readmem[0xa000+j] = read_rdramFB;
1332                             readmemb[0xa000+j] = read_rdramFBb;
1333                             readmemh[0xa000+j] = read_rdramFBh;
1334                             readmemd[0x8000+j] = read_rdramFBd;
1335 #ifdef DBG
1336                         }
1337                         if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000,
1338                                               BPT_FLAG_ENABLED |  BPT_FLAG_WRITE ) != -1)
1339                         {
1340                             writemem[0x8000+j] = write_rdramFB_break;
1341                             writememb[0x8000+j] = write_rdramFBb_break;
1342                             writememh[0x8000+j] = write_rdramFBh_break;
1343                             writememd[0x8000+j] = write_rdramFBd_break;
1344                         }
1345                         else
1346                         {
1347 #endif
1348                             writemem[0x8000+j] = write_rdramFB;
1349                             writememb[0x8000+j] = write_rdramFBb;
1350                             writememh[0x8000+j] = write_rdramFBh;
1351                             writememd[0x8000+j] = write_rdramFBd;
1352 #ifdef DBG
1353                         }
1354                         if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000,
1355                                               BPT_FLAG_ENABLED |  BPT_FLAG_WRITE ) != -1)
1356                         {
1357                             writemem[0xa000+j] = write_rdramFB_break;
1358                             writememb[0xa000+j] = write_rdramFBb_break;
1359                             writememh[0xa000+j] = write_rdramFBh_break;
1360                             writememd[0xa000+j] = write_rdramFBd_break;
1361                         }
1362                         else
1363                         {
1364 #endif
1365                             writemem[0xa000+j] = write_rdramFB;
1366                             writememb[0xa000+j] = write_rdramFBb;
1367                             writememh[0xa000+j] = write_rdramFBh;
1368                             writememd[0xa000+j] = write_rdramFBd;
1369 #ifdef DBG
1370                         }
1371 #endif
1372                     }
1373                     start <<= 4;
1374                     end <<= 4;
1375                     for (j=start; j<=end; j++)
1376                     {
1377                         if (j>=start1 && j<=end1) framebufferRead[j]=1;
1378                         else framebufferRead[j] = 0;
1379                     }
1380
1381                     if (firstFrameBufferSetting)
1382                     {
1383                         firstFrameBufferSetting = 0;
1384                         fast_memory = 0;
1385                         for (j=0; j<0x100000; j++)
1386                             invalid_code[j] = 1;
1387                     }
1388                 }
1389             }
1390         }
1391     }
1392     else if (SP_DMEM[0xFC0/4] == 2)
1393     {
1394         //audio.processAList();
1395         rsp_register.rsp_pc &= 0xFFF;
1396         start_section(AUDIO_SECTION);
1397         rsp.doRspCycles(0xFFFFFFFF);
1398         end_section(AUDIO_SECTION);
1399         rsp_register.rsp_pc |= save_pc;
1400
1401         update_count();
1402         if (MI_register.mi_intr_reg & 0x1)
1403             add_interupt_event(SP_INT, 4000/*500*/);
1404         MI_register.mi_intr_reg &= ~0x1;
1405         sp_register.sp_status_reg &= ~0x303;
1406         
1407     }
1408     else
1409     {
1410         rsp_register.rsp_pc &= 0xFFF;
1411         rsp.doRspCycles(0xFFFFFFFF);
1412         rsp_register.rsp_pc |= save_pc;
1413
1414         update_count();
1415         if (MI_register.mi_intr_reg & 0x1)
1416             add_interupt_event(SP_INT, 0/*100*/);
1417         MI_register.mi_intr_reg &= ~0x1;
1418         sp_register.sp_status_reg &= ~0x203;
1419     }
1420 }
1421
1422 static void update_SP(void)
1423 {
1424     if (sp_register.w_sp_status_reg & 0x1) // clear halt
1425         sp_register.sp_status_reg &= ~0x1;
1426     if (sp_register.w_sp_status_reg & 0x2) // set halt
1427         sp_register.sp_status_reg |= 0x1;
1428
1429     if (sp_register.w_sp_status_reg & 0x4) // clear broke
1430         sp_register.sp_status_reg &= ~0x2;
1431
1432     if (sp_register.w_sp_status_reg & 0x8) // clear SP interupt
1433     {
1434         MI_register.mi_intr_reg &= ~1;
1435         check_interupt();
1436     }
1437
1438     if (sp_register.w_sp_status_reg & 0x10) // set SP interupt
1439     {
1440         MI_register.mi_intr_reg |= 1;
1441         check_interupt();
1442     }
1443
1444     if (sp_register.w_sp_status_reg & 0x20) // clear single step
1445         sp_register.sp_status_reg &= ~0x20;
1446     if (sp_register.w_sp_status_reg & 0x40) // set single step
1447         sp_register.sp_status_reg |= 0x20;
1448
1449     if (sp_register.w_sp_status_reg & 0x80) // clear interrupt on break
1450         sp_register.sp_status_reg &= ~0x40;
1451     if (sp_register.w_sp_status_reg & 0x100) // set interrupt on break
1452         sp_register.sp_status_reg |= 0x40;
1453
1454     if (sp_register.w_sp_status_reg & 0x200) // clear signal 0
1455         sp_register.sp_status_reg &= ~0x80;
1456     if (sp_register.w_sp_status_reg & 0x400) // set signal 0
1457         sp_register.sp_status_reg |= 0x80;
1458
1459     if (sp_register.w_sp_status_reg & 0x800) // clear signal 1
1460         sp_register.sp_status_reg &= ~0x100;
1461     if (sp_register.w_sp_status_reg & 0x1000) // set signal 1
1462         sp_register.sp_status_reg |= 0x100;
1463
1464     if (sp_register.w_sp_status_reg & 0x2000) // clear signal 2
1465         sp_register.sp_status_reg &= ~0x200;
1466     if (sp_register.w_sp_status_reg & 0x4000) // set signal 2
1467         sp_register.sp_status_reg |= 0x200;
1468
1469     if (sp_register.w_sp_status_reg & 0x8000) // clear signal 3
1470         sp_register.sp_status_reg &= ~0x400;
1471     if (sp_register.w_sp_status_reg & 0x10000) // set signal 3
1472         sp_register.sp_status_reg |= 0x400;
1473
1474     if (sp_register.w_sp_status_reg & 0x20000) // clear signal 4
1475         sp_register.sp_status_reg &= ~0x800;
1476     if (sp_register.w_sp_status_reg & 0x40000) // set signal 4
1477         sp_register.sp_status_reg |= 0x800;
1478
1479     if (sp_register.w_sp_status_reg & 0x80000) // clear signal 5
1480         sp_register.sp_status_reg &= ~0x1000;
1481     if (sp_register.w_sp_status_reg & 0x100000) // set signal 5
1482         sp_register.sp_status_reg |= 0x1000;
1483
1484     if (sp_register.w_sp_status_reg & 0x200000) // clear signal 6
1485         sp_register.sp_status_reg &= ~0x2000;
1486     if (sp_register.w_sp_status_reg & 0x400000) // set signal 6
1487         sp_register.sp_status_reg |= 0x2000;
1488
1489     if (sp_register.w_sp_status_reg & 0x800000) // clear signal 7
1490         sp_register.sp_status_reg &= ~0x4000;
1491     if (sp_register.w_sp_status_reg & 0x1000000) // set signal 7
1492         sp_register.sp_status_reg |= 0x4000;
1493
1494     //if (get_event(SP_INT)) return;
1495     if (!(sp_register.w_sp_status_reg & 0x1) &&
1496             !(sp_register.w_sp_status_reg & 0x4)) return;
1497     if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke
1498         do_SP_Task();
1499 }
1500
1501 void make_w_dpc_status(void)
1502 {
1503     dpc_register.w_dpc_status = 0;
1504
1505     if ((dpc_register.dpc_status & 0x0001) == 0)
1506         dpc_register.w_dpc_status |= 0x0000001;
1507     else
1508         dpc_register.w_dpc_status |= 0x0000002;
1509
1510     if ((dpc_register.dpc_status & 0x0002) == 0)
1511         dpc_register.w_dpc_status |= 0x0000004;
1512     else
1513         dpc_register.w_dpc_status |= 0x0000008;
1514
1515     if ((dpc_register.dpc_status & 0x0004) == 0)
1516         dpc_register.w_dpc_status |= 0x0000010;
1517     else
1518         dpc_register.w_dpc_status |= 0x0000020;
1519 }
1520
1521 static void update_DPC(void)
1522 {
1523     if (dpc_register.w_dpc_status & 0x1) // clear xbus_dmem_dma
1524         dpc_register.dpc_status &= ~0x1;
1525     if (dpc_register.w_dpc_status & 0x2) // set xbus_dmem_dma
1526         dpc_register.dpc_status |= 0x1;
1527
1528     if (dpc_register.w_dpc_status & 0x4) // clear freeze
1529     {
1530         dpc_register.dpc_status &= ~0x2;
1531
1532         // see do_SP_task for more info
1533         if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke
1534             do_SP_Task();
1535     }
1536     if (dpc_register.w_dpc_status & 0x8) // set freeze
1537         dpc_register.dpc_status |= 0x2;
1538
1539     if (dpc_register.w_dpc_status & 0x10) // clear flush
1540         dpc_register.dpc_status &= ~0x4;
1541     if (dpc_register.w_dpc_status & 0x20) // set flush
1542         dpc_register.dpc_status |= 0x4;
1543 }
1544
1545 void read_nothing(void)
1546 {
1547     if (address == 0xa5000508) *rdword = 0xFFFFFFFF;
1548     else *rdword = 0;
1549 }
1550
1551 void read_nothingb(void)
1552 {
1553     *rdword = 0;
1554 }
1555
1556 void read_nothingh(void)
1557 {
1558     *rdword = 0;
1559 }
1560
1561 void read_nothingd(void)
1562 {
1563     *rdword = 0;
1564 }
1565
1566 void write_nothing(void)
1567 {
1568 }
1569
1570 void write_nothingb(void)
1571 {
1572 }
1573
1574 void write_nothingh(void)
1575 {
1576 }
1577
1578 void write_nothingd(void)
1579 {
1580 }
1581
1582 void read_nomem(void)
1583 {
1584     address = virtual_to_physical_address(address,0);
1585     if (address == 0x00000000) return;
1586     read_word_in_memory();
1587 }
1588
1589 void read_nomemb(void)
1590 {
1591     address = virtual_to_physical_address(address,0);
1592     if (address == 0x00000000) return;
1593     read_byte_in_memory();
1594 }
1595
1596 void read_nomemh(void)
1597 {
1598     address = virtual_to_physical_address(address,0);
1599     if (address == 0x00000000) return;
1600     read_hword_in_memory();
1601 }
1602
1603 void read_nomemd(void)
1604 {
1605     address = virtual_to_physical_address(address,0);
1606     if (address == 0x00000000) return;
1607     read_dword_in_memory();
1608 }
1609
1610 void write_nomem(void)
1611 {
1612     if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12])
1613         if (blocks[address>>12]->block[(address&0xFFF)/4].ops !=
1614             current_instruction_table.NOTCOMPILED)
1615             invalid_code[address>>12] = 1;
1616     address = virtual_to_physical_address(address,1);
1617     if (address == 0x00000000) return;
1618     write_word_in_memory();
1619 }
1620
1621 void write_nomemb(void)
1622 {
1623     if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12])
1624         if (blocks[address>>12]->block[(address&0xFFF)/4].ops != 
1625             current_instruction_table.NOTCOMPILED)
1626             invalid_code[address>>12] = 1;
1627     address = virtual_to_physical_address(address,1);
1628     if (address == 0x00000000) return;
1629     write_byte_in_memory();
1630 }
1631
1632 void write_nomemh(void)
1633 {
1634     if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12])
1635         if (blocks[address>>12]->block[(address&0xFFF)/4].ops != 
1636             current_instruction_table.NOTCOMPILED)
1637             invalid_code[address>>12] = 1;
1638     address = virtual_to_physical_address(address,1);
1639     if (address == 0x00000000) return;
1640     write_hword_in_memory();
1641 }
1642
1643 void write_nomemd(void)
1644 {
1645     if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12])
1646         if (blocks[address>>12]->block[(address&0xFFF)/4].ops != 
1647             current_instruction_table.NOTCOMPILED)
1648             invalid_code[address>>12] = 1;
1649     address = virtual_to_physical_address(address,1);
1650     if (address == 0x00000000) return;
1651     write_dword_in_memory();
1652 }
1653
1654 void read_rdram(void)
1655 {
1656     *rdword = *((unsigned int *)(rdramb + (address & 0xFFFFFF)));
1657 }
1658
1659 void read_rdramb(void)
1660 {
1661     *rdword = *(rdramb + ((address & 0xFFFFFF)^S8));
1662 }
1663
1664 void read_rdramh(void)
1665 {
1666     *rdword = *((unsigned short *)(rdramb + ((address & 0xFFFFFF)^S16)));
1667 }
1668
1669 void read_rdramd(void)
1670 {
1671     *rdword = ((unsigned long long int)(*(unsigned int *)(rdramb + (address & 0xFFFFFF))) << 32) |
1672               ((*(unsigned int *)(rdramb + (address & 0xFFFFFF) + 4)));
1673 }
1674
1675 void read_rdramFB(void)
1676 {
1677     int i;
1678     for (i=0; i<6; i++)
1679     {
1680         if (frameBufferInfos[i].addr)
1681         {
1682             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1683             unsigned int end = start + frameBufferInfos[i].width*
1684                                frameBufferInfos[i].height*
1685                                frameBufferInfos[i].size - 1;
1686             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end &&
1687                     framebufferRead[(address & 0x7FFFFF)>>12])
1688             {
1689                 gfx.fBRead(address);
1690                 framebufferRead[(address & 0x7FFFFF)>>12] = 0;
1691             }
1692         }
1693     }
1694     read_rdram();
1695 }
1696
1697 void read_rdramFBb(void)
1698 {
1699     int i;
1700     for (i=0; i<6; i++)
1701     {
1702         if (frameBufferInfos[i].addr)
1703         {
1704             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1705             unsigned int end = start + frameBufferInfos[i].width*
1706                                frameBufferInfos[i].height*
1707                                frameBufferInfos[i].size - 1;
1708             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end &&
1709                     framebufferRead[(address & 0x7FFFFF)>>12])
1710             {
1711                 gfx.fBRead(address);
1712                 framebufferRead[(address & 0x7FFFFF)>>12] = 0;
1713             }
1714         }
1715     }
1716     read_rdramb();
1717 }
1718
1719 void read_rdramFBh(void)
1720 {
1721     int i;
1722     for (i=0; i<6; i++)
1723     {
1724         if (frameBufferInfos[i].addr)
1725         {
1726             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1727             unsigned int end = start + frameBufferInfos[i].width*
1728                                frameBufferInfos[i].height*
1729                                frameBufferInfos[i].size - 1;
1730             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end &&
1731                     framebufferRead[(address & 0x7FFFFF)>>12])
1732             {
1733                 gfx.fBRead(address);
1734                 framebufferRead[(address & 0x7FFFFF)>>12] = 0;
1735             }
1736         }
1737     }
1738     read_rdramh();
1739 }
1740
1741 void read_rdramFBd(void)
1742 {
1743     int i;
1744     for (i=0; i<6; i++)
1745     {
1746         if (frameBufferInfos[i].addr)
1747         {
1748             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1749             unsigned int end = start + frameBufferInfos[i].width*
1750                                frameBufferInfos[i].height*
1751                                frameBufferInfos[i].size - 1;
1752             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end &&
1753                     framebufferRead[(address & 0x7FFFFF)>>12])
1754             {
1755                 gfx.fBRead(address);
1756                 framebufferRead[(address & 0x7FFFFF)>>12] = 0;
1757             }
1758         }
1759     }
1760     read_rdramd();
1761 }
1762
1763 void write_rdram(void)
1764 {
1765 #if defined( COUNT_WRITE_RDRAM_CALLS )
1766         printf( "write_rdram, word=%i, count: %i", word, writerdram_count );
1767         writerdram_count++;
1768 #endif
1769     *((unsigned int *)(rdramb + (address & 0xFFFFFF))) = word;
1770 }
1771
1772 void write_rdramb(void)
1773 {
1774     *((rdramb + ((address & 0xFFFFFF)^S8))) = cpu_byte;
1775 }
1776
1777 void write_rdramh(void)
1778 {
1779     *(unsigned short *)((rdramb + ((address & 0xFFFFFF)^S16))) = hword;
1780 }
1781
1782 void write_rdramd(void)
1783 {
1784     *((unsigned int *)(rdramb + (address & 0xFFFFFF))) = (unsigned int) (dword >> 32);
1785     *((unsigned int *)(rdramb + (address & 0xFFFFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
1786 }
1787
1788 void write_rdramFB(void)
1789 {
1790     int i;
1791     for (i=0; i<6; i++)
1792     {
1793         if (frameBufferInfos[i].addr)
1794         {
1795             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1796             unsigned int end = start + frameBufferInfos[i].width*
1797                                frameBufferInfos[i].height*
1798                                frameBufferInfos[i].size - 1;
1799             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end)
1800                 gfx.fBWrite(address, 4);
1801         }
1802     }
1803     write_rdram();
1804 }
1805
1806 void write_rdramFBb(void)
1807 {
1808     int i;
1809     for (i=0; i<6; i++)
1810     {
1811         if (frameBufferInfos[i].addr)
1812         {
1813             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1814             unsigned int end = start + frameBufferInfos[i].width*
1815                                frameBufferInfos[i].height*
1816                                frameBufferInfos[i].size - 1;
1817             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end)
1818                 gfx.fBWrite(address^S8, 1);
1819         }
1820     }
1821     write_rdramb();
1822 }
1823
1824 void write_rdramFBh(void)
1825 {
1826     int i;
1827     for (i=0; i<6; i++)
1828     {
1829         if (frameBufferInfos[i].addr)
1830         {
1831             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1832             unsigned int end = start + frameBufferInfos[i].width*
1833                                frameBufferInfos[i].height*
1834                                frameBufferInfos[i].size - 1;
1835             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end)
1836                 gfx.fBWrite(address^S16, 2);
1837         }
1838     }
1839     write_rdramh();
1840 }
1841
1842 void write_rdramFBd(void)
1843 {
1844     int i;
1845     for (i=0; i<6; i++)
1846     {
1847         if (frameBufferInfos[i].addr)
1848         {
1849             unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF;
1850             unsigned int end = start + frameBufferInfos[i].width*
1851                                frameBufferInfos[i].height*
1852                                frameBufferInfos[i].size - 1;
1853             if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end)
1854                 gfx.fBWrite(address, 8);
1855         }
1856     }
1857     write_rdramd();
1858 }
1859
1860 void read_rdramreg(void)
1861 {
1862     *rdword = *(readrdramreg[*address_low]);
1863 }
1864
1865 void read_rdramregb(void)
1866 {
1867     *rdword = *((unsigned char*)readrdramreg[*address_low & 0xfffc]
1868                 + ((*address_low&3)^S8) );
1869 }
1870
1871 void read_rdramregh(void)
1872 {
1873     *rdword = *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc]
1874                                   + ((*address_low&3)^S16) ));
1875 }
1876
1877 void read_rdramregd(void)
1878 {
1879     *rdword = ((unsigned long long int)(*readrdramreg[*address_low])<<32) |
1880               *readrdramreg[*address_low+4];
1881 }
1882
1883 void write_rdramreg(void)
1884 {
1885     *readrdramreg[*address_low] = word;
1886 }
1887
1888 void write_rdramregb(void)
1889 {
1890     *((unsigned char*)readrdramreg[*address_low & 0xfffc]
1891       + ((*address_low&3)^S8) ) = cpu_byte;
1892 }
1893
1894 void write_rdramregh(void)
1895 {
1896     *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc]
1897                         + ((*address_low&3)^S16) )) = hword;
1898 }
1899
1900 void write_rdramregd(void)
1901 {
1902     *readrdramreg[*address_low] = (unsigned int) (dword >> 32);
1903     *readrdramreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
1904 }
1905
1906 void read_rsp_mem(void)
1907 {
1908     if (*address_low < 0x1000)
1909         *rdword = *((unsigned int *)(SP_DMEMb + (*address_low)));
1910     else if (*address_low < 0x2000)
1911         *rdword = *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF)));
1912     else
1913         read_nomem();
1914 }
1915
1916 void read_rsp_memb(void)
1917 {
1918     if (*address_low < 0x1000)
1919         *rdword = *(SP_DMEMb + (*address_low^S8));
1920     else if (*address_low < 0x2000)
1921         *rdword = *(SP_IMEMb + ((*address_low&0xFFF)^S8));
1922     else
1923         read_nomemb();
1924 }
1925
1926 void read_rsp_memh(void)
1927 {
1928     if (*address_low < 0x1000)
1929         *rdword = *((unsigned short *)(SP_DMEMb + (*address_low^S16)));
1930     else if (*address_low < 0x2000)
1931         *rdword = *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16)));
1932     else
1933         read_nomemh();
1934 }
1935
1936 void read_rsp_memd(void)
1937 {
1938     if (*address_low < 0x1000)
1939     {
1940         *rdword = ((unsigned long long int)(*(unsigned int *)(SP_DMEMb + (*address_low))) << 32) |
1941                   ((*(unsigned int *)(SP_DMEMb + (*address_low) + 4)));
1942     }
1943     else if (*address_low < 0x2000)
1944     {
1945         *rdword = ((unsigned long long int)(*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) << 32) |
1946                   ((*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4)));
1947     }
1948     else
1949         read_nomemd();
1950 }
1951
1952 void write_rsp_mem(void)
1953 {
1954     if (*address_low < 0x1000)
1955         *((unsigned int *)(SP_DMEMb + (*address_low))) = word;
1956     else if (*address_low < 0x2000)
1957         *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = word;
1958     else
1959         write_nomem();
1960 }
1961
1962 void write_rsp_memb(void)
1963 {
1964     if (*address_low < 0x1000)
1965         *(SP_DMEMb + (*address_low^S8)) = cpu_byte;
1966     else if (*address_low < 0x2000)
1967         *(SP_IMEMb + ((*address_low&0xFFF)^S8)) = cpu_byte;
1968     else
1969         write_nomemb();
1970 }
1971
1972 void write_rsp_memh(void)
1973 {
1974     if (*address_low < 0x1000)
1975         *((unsigned short *)(SP_DMEMb + (*address_low^S16))) = hword;
1976     else if (*address_low < 0x2000)
1977         *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))) = hword;
1978     else
1979         write_nomemh();
1980 }
1981
1982 void write_rsp_memd(void)
1983 {
1984     if (*address_low < 0x1000)
1985     {
1986         *((unsigned int *)(SP_DMEMb + *address_low)) = (unsigned int) (dword >> 32);
1987         *((unsigned int *)(SP_DMEMb + *address_low + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
1988     }
1989     else if (*address_low < 0x2000)
1990     {
1991         *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = (unsigned int) (dword >> 32);
1992         *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
1993     }
1994     else
1995         read_nomemd();
1996 }
1997
1998 void read_rsp_reg(void)
1999 {
2000     *rdword = *(readrspreg[*address_low]);
2001     switch (*address_low)
2002     {
2003     case 0x1c:
2004         sp_register.sp_semaphore_reg = 1;
2005         break;
2006     }
2007 }
2008
2009 void read_rsp_regb(void)
2010 {
2011     *rdword = *((unsigned char*)readrspreg[*address_low & 0xfffc]
2012                 + ((*address_low&3)^S8) );
2013     switch (*address_low)
2014     {
2015     case 0x1c:
2016     case 0x1d:
2017     case 0x1e:
2018     case 0x1f:
2019         sp_register.sp_semaphore_reg = 1;
2020         break;
2021     }
2022 }
2023
2024 void read_rsp_regh(void)
2025 {
2026     *rdword = *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc]
2027                                   + ((*address_low&3)^S16) ));
2028     switch (*address_low)
2029     {
2030     case 0x1c:
2031     case 0x1e:
2032         sp_register.sp_semaphore_reg = 1;
2033         break;
2034     }
2035 }
2036
2037 void read_rsp_regd(void)
2038 {
2039     *rdword = ((unsigned long long int)(*readrspreg[*address_low])<<32) |
2040               *readrspreg[*address_low+4];
2041     switch (*address_low)
2042     {
2043     case 0x18:
2044         sp_register.sp_semaphore_reg = 1;
2045         break;
2046     }
2047 }
2048
2049 void write_rsp_reg(void)
2050 {
2051     switch (*address_low)
2052     {
2053     case 0x10:
2054         sp_register.w_sp_status_reg = word;
2055         update_SP();
2056     case 0x14:
2057     case 0x18:
2058         return;
2059         break;
2060     }
2061     *readrspreg[*address_low] = word;
2062     switch (*address_low)
2063     {
2064     case 0x8:
2065         dma_sp_write();
2066         break;
2067     case 0xc:
2068         dma_sp_read();
2069         break;
2070     case 0x1c:
2071         sp_register.sp_semaphore_reg = 0;
2072         break;
2073     }
2074 }
2075
2076 void write_rsp_regb(void)
2077 {
2078     switch (*address_low)
2079     {
2080     case 0x10:
2081     case 0x11:
2082     case 0x12:
2083     case 0x13:
2084         *((unsigned char*)&sp_register.w_sp_status_reg
2085           + ((*address_low&3)^S8) ) = cpu_byte;
2086     case 0x14:
2087     case 0x15:
2088     case 0x16:
2089     case 0x17:
2090     case 0x18:
2091     case 0x19:
2092     case 0x1a:
2093     case 0x1b:
2094         return;
2095         break;
2096     }
2097     *((unsigned char*)readrspreg[*address_low & 0xfffc]
2098       + ((*address_low&3)^S8) ) = cpu_byte;
2099     switch (*address_low)
2100     {
2101     case 0x8:
2102     case 0x9:
2103     case 0xa:
2104     case 0xb:
2105         dma_sp_write();
2106         break;
2107     case 0xc:
2108     case 0xd:
2109     case 0xe:
2110     case 0xf:
2111         dma_sp_read();
2112         break;
2113     case 0x1c:
2114     case 0x1d:
2115     case 0x1e:
2116     case 0x1f:
2117         sp_register.sp_semaphore_reg = 0;
2118         break;
2119     }
2120 }
2121
2122 void write_rsp_regh(void)
2123 {
2124     switch (*address_low)
2125     {
2126     case 0x10:
2127     case 0x12:
2128         *((unsigned short*)((unsigned char*)&sp_register.w_sp_status_reg
2129                             + ((*address_low&3)^S16) )) = hword;
2130     case 0x14:
2131     case 0x16:
2132     case 0x18:
2133     case 0x1a:
2134         return;
2135         break;
2136     }
2137     *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc]
2138                         + ((*address_low&3)^S16) )) = hword;
2139     switch (*address_low)
2140     {
2141     case 0x8:
2142     case 0xa:
2143         dma_sp_write();
2144         break;
2145     case 0xc:
2146     case 0xe:
2147         dma_sp_read();
2148         break;
2149     case 0x1c:
2150     case 0x1e:
2151         sp_register.sp_semaphore_reg = 0;
2152         break;
2153     }
2154 }
2155
2156 void write_rsp_regd(void)
2157 {
2158     switch (*address_low)
2159     {
2160     case 0x10:
2161         sp_register.w_sp_status_reg = (unsigned int) (dword >> 32);
2162         update_SP();
2163         return;
2164         break;
2165     case 0x18:
2166         sp_register.sp_semaphore_reg = 0;
2167         return;
2168         break;
2169     }
2170     *readrspreg[*address_low] = (unsigned int) (dword >> 32);
2171     *readrspreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
2172     switch (*address_low)
2173     {
2174     case 0x8:
2175         dma_sp_write();
2176         dma_sp_read();
2177         break;
2178     }
2179 }
2180
2181 void read_rsp(void)
2182 {
2183     *rdword = *(readrsp[*address_low]);
2184 }
2185
2186 void read_rspb(void)
2187 {
2188     *rdword = *((unsigned char*)readrsp[*address_low & 0xfffc]
2189                 + ((*address_low&3)^S8) );
2190 }
2191
2192 void read_rsph(void)
2193 {
2194     *rdword = *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
2195                                   + ((*address_low&3)^S16) ));
2196 }
2197
2198 void read_rspd(void)
2199 {
2200     *rdword = ((unsigned long long int)(*readrsp[*address_low])<<32) |
2201               *readrsp[*address_low+4];
2202 }
2203
2204 void write_rsp(void)
2205 {
2206     *readrsp[*address_low] = word;
2207 }
2208
2209 void write_rspb(void)
2210 {
2211     *((unsigned char*)readrsp[*address_low & 0xfffc]
2212       + ((*address_low&3)^S8) ) = cpu_byte;
2213 }
2214
2215 void write_rsph(void)
2216 {
2217     *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
2218                         + ((*address_low&3)^S16) )) = hword;
2219 }
2220
2221 void write_rspd(void)
2222 {
2223     *readrsp[*address_low] = (unsigned int) (dword >> 32);
2224     *readrsp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
2225 }
2226
2227 void read_dp(void)
2228 {
2229     *rdword = *(readdp[*address_low]);
2230 }
2231
2232 void read_dpb(void)
2233 {
2234     *rdword = *((unsigned char*)readdp[*address_low & 0xfffc]
2235                 + ((*address_low&3)^S8) );
2236 }
2237
2238 void read_dph(void)
2239 {
2240     *rdword = *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc]
2241                                   + ((*address_low&3)^S16) ));
2242 }
2243
2244 void read_dpd(void)
2245 {
2246     *rdword = ((unsigned long long int)(*readdp[*address_low])<<32) |
2247               *readdp[*address_low+4];
2248 }
2249
2250 void write_dp(void)
2251 {
2252     switch (*address_low)
2253     {
2254     case 0xc:
2255         dpc_register.w_dpc_status = word;
2256         update_DPC();
2257     case 0x8:
2258     case 0x10:
2259     case 0x14:
2260     case 0x18:
2261     case 0x1c:
2262         return;
2263         break;
2264     }
2265     *readdp[*address_low] = word;
2266     switch (*address_low)
2267     {
2268     case 0x0:
2269         dpc_register.dpc_current = dpc_register.dpc_start;
2270         break;
2271     case 0x4:
2272         gfx.processRDPList();
2273         MI_register.mi_intr_reg |= 0x20;
2274         check_interupt();
2275         break;
2276     }
2277 }
2278
2279 void write_dpb(void)
2280 {
2281     switch (*address_low)
2282     {
2283     case 0xc:
2284     case 0xd:
2285     case 0xe:
2286     case 0xf:
2287         *((unsigned char*)&dpc_register.w_dpc_status
2288           + ((*address_low&3)^S8) ) = cpu_byte;
2289         update_DPC();
2290     case 0x8:
2291     case 0x9:
2292     case 0xa:
2293     case 0xb:
2294     case 0x10:
2295     case 0x11:
2296     case 0x12:
2297     case 0x13:
2298     case 0x14:
2299     case 0x15:
2300     case 0x16:
2301     case 0x17:
2302     case 0x18:
2303     case 0x19:
2304     case 0x1a:
2305     case 0x1b:
2306     case 0x1c:
2307     case 0x1d:
2308     case 0x1e:
2309     case 0x1f:
2310         return;
2311         break;
2312     }
2313     *((unsigned char*)readdp[*address_low & 0xfffc]
2314       + ((*address_low&3)^S8) ) = cpu_byte;
2315     switch (*address_low)
2316     {
2317     case 0x0:
2318     case 0x1:
2319     case 0x2:
2320     case 0x3:
2321         dpc_register.dpc_current = dpc_register.dpc_start;
2322         break;
2323     case 0x4:
2324     case 0x5:
2325     case 0x6:
2326     case 0x7:
2327         gfx.processRDPList();
2328         MI_register.mi_intr_reg |= 0x20;
2329         check_interupt();
2330         break;
2331     }
2332 }
2333
2334 void write_dph(void)
2335 {
2336     switch (*address_low)
2337     {
2338     case 0xc:
2339     case 0xe:
2340         *((unsigned short*)((unsigned char*)&dpc_register.w_dpc_status
2341                             + ((*address_low&3)^S16) )) = hword;
2342         update_DPC();
2343     case 0x8:
2344     case 0xa:
2345     case 0x10:
2346     case 0x12:
2347     case 0x14:
2348     case 0x16:
2349     case 0x18:
2350     case 0x1a:
2351     case 0x1c:
2352     case 0x1e:
2353         return;
2354         break;
2355     }
2356     *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc]
2357                         + ((*address_low&3)^S16) )) = hword;
2358     switch (*address_low)
2359     {
2360     case 0x0:
2361     case 0x2:
2362         dpc_register.dpc_current = dpc_register.dpc_start;
2363         break;
2364     case 0x4:
2365     case 0x6:
2366         gfx.processRDPList();
2367         MI_register.mi_intr_reg |= 0x20;
2368         check_interupt();
2369         break;
2370     }
2371 }
2372
2373 void write_dpd(void)
2374 {
2375     switch (*address_low)
2376     {
2377     case 0x8:
2378         dpc_register.w_dpc_status = (unsigned int) (dword & 0xFFFFFFFF);
2379         update_DPC();
2380         return;
2381         break;
2382     case 0x10:
2383     case 0x18:
2384         return;
2385         break;
2386     }
2387     *readdp[*address_low] = (unsigned int) (dword >> 32);
2388     *readdp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
2389     switch (*address_low)
2390     {
2391     case 0x0:
2392         dpc_register.dpc_current = dpc_register.dpc_start;
2393         gfx.processRDPList();
2394         MI_register.mi_intr_reg |= 0x20;
2395         check_interupt();
2396         break;
2397     }
2398 }
2399
2400 void read_dps(void)
2401 {
2402     *rdword = *(readdps[*address_low]);
2403 }
2404
2405 void read_dpsb(void)
2406 {
2407     *rdword = *((unsigned char*)readdps[*address_low & 0xfffc]
2408                 + ((*address_low&3)^S8) );
2409 }
2410
2411 void read_dpsh(void)
2412 {
2413     *rdword = *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
2414                                   + ((*address_low&3)^S16) ));
2415 }
2416
2417 void read_dpsd(void)
2418 {
2419     *rdword = ((unsigned long long int)(*readdps[*address_low])<<32) |
2420               *readdps[*address_low+4];
2421 }
2422
2423 void write_dps(void)
2424 {
2425     *readdps[*address_low] = word;
2426 }
2427
2428 void write_dpsb(void)
2429 {
2430     *((unsigned char*)readdps[*address_low & 0xfffc]
2431       + ((*address_low&3)^S8) ) = cpu_byte;
2432 }
2433
2434 void write_dpsh(void)
2435 {
2436     *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
2437                         + ((*address_low&3)^S16) )) = hword;
2438 }
2439
2440 void write_dpsd(void)
2441 {
2442     *readdps[*address_low] = (unsigned int) (dword >> 32);
2443     *readdps[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
2444 }
2445
2446 void read_mi(void)
2447 {
2448     *rdword = *(readmi[*address_low]);
2449 }
2450
2451 void read_mib(void)
2452 {
2453     *rdword = *((unsigned char*)readmi[*address_low & 0xfffc]
2454                 + ((*address_low&3)^S8) );
2455 }
2456
2457 void read_mih(void)
2458 {
2459     *rdword = *((unsigned short*)((unsigned char*)readmi[*address_low & 0xfffc]
2460                                   + ((*address_low&3)^S16) ));
2461 }
2462
2463 void read_mid(void)
2464 {
2465     *rdword = ((unsigned long long int)(*readmi[*address_low])<<32) |
2466               *readmi[*address_low+4];
2467 }
2468
2469 void write_mi(void)
2470 {
2471     switch (*address_low)
2472     {
2473     case 0x0:
2474         MI_register.w_mi_init_mode_reg = word;
2475         update_MI_init_mode_reg();
2476         break;
2477     case 0xc:
2478         MI_register.w_mi_intr_mask_reg = word;
2479         update_MI_intr_mask_reg();
2480
2481         check_interupt();
2482         update_count();
2483         if (next_interupt <= Count) gen_interupt();
2484         break;
2485     }
2486 }
2487
2488 void write_mib(void)
2489 {
2490     switch (*address_low)
2491     {
2492     case 0x0:
2493     case 0x1:
2494     case 0x2:
2495     case 0x3:
2496         *((unsigned char*)&MI_register.w_mi_init_mode_reg
2497           + ((*address_low&3)^S8) ) = cpu_byte;
2498         update_MI_init_mode_reg();
2499         break;
2500     case 0xc:
2501     case 0xd:
2502     case 0xe:
2503     case 0xf:
2504         *((unsigned char*)&MI_register.w_mi_intr_mask_reg
2505           + ((*address_low&3)^S8) ) = cpu_byte;
2506         update_MI_intr_mask_reg();
2507
2508         check_interupt();
2509         update_count();
2510         if (next_interupt <= Count) gen_interupt();
2511         break;
2512     }
2513 }
2514
2515 void write_mih(void)
2516 {
2517     switch (*address_low)
2518     {
2519     case 0x0:
2520     case 0x2:
2521         *((unsigned short*)((unsigned char*)&MI_register.w_mi_init_mode_reg
2522                             + ((*address_low&3)^S16) )) = hword;
2523         update_MI_init_mode_reg();
2524         break;
2525     case 0xc:
2526     case 0xe:
2527         *((unsigned short*)((unsigned char*)&MI_register.w_mi_intr_mask_reg
2528                             + ((*address_low&3)^S16) )) = hword;
2529         update_MI_intr_mask_reg();
2530
2531         check_interupt();
2532         update_count();
2533         if (next_interupt <= Count) gen_interupt();
2534         break;
2535     }
2536 }
2537
2538 void write_mid(void)
2539 {
2540     switch (*address_low)
2541     {
2542     case 0x0:
2543         MI_register.w_mi_init_mode_reg = (unsigned int) (dword >> 32);
2544         update_MI_init_mode_reg();
2545         break;
2546     case 0x8:
2547         MI_register.w_mi_intr_mask_reg = (unsigned int) (dword & 0xFFFFFFFF);
2548         update_MI_intr_mask_reg();
2549
2550         check_interupt();
2551         update_count();
2552         if (next_interupt <= Count) gen_interupt();
2553         break;
2554     }
2555 }
2556
2557 void read_vi(void)
2558 {
2559     switch (*address_low)
2560     {
2561     case 0x10:
2562         update_count();
2563         vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500;
2564         vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field;
2565         break;
2566     }
2567     *rdword = *(readvi[*address_low]);
2568 }
2569
2570 void read_vib(void)
2571 {
2572     switch (*address_low)
2573     {
2574     case 0x10:
2575     case 0x11:
2576     case 0x12:
2577     case 0x13:
2578         update_count();
2579         vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500;
2580         vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field;
2581         break;
2582     }
2583     *rdword = *((unsigned char*)readvi[*address_low & 0xfffc]
2584                 + ((*address_low&3)^S8) );
2585 }
2586
2587 void read_vih(void)
2588 {
2589     switch (*address_low)
2590     {
2591     case 0x10:
2592     case 0x12:
2593         update_count();
2594         vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500;
2595         vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field;
2596         break;
2597     }
2598     *rdword = *((unsigned short*)((unsigned char*)readvi[*address_low & 0xfffc]
2599                                   + ((*address_low&3)^S16) ));
2600 }
2601
2602 void read_vid(void)
2603 {
2604     switch (*address_low)
2605     {
2606     case 0x10:
2607         update_count();
2608         vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500;
2609         vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field;
2610         break;
2611     }
2612     *rdword = ((unsigned long long int)(*readvi[*address_low])<<32) |
2613               *readvi[*address_low+4];
2614 }
2615
2616 void write_vi(void)
2617 {
2618     switch (*address_low)
2619     {
2620     case 0x0:
2621         if (vi_register.vi_status != word)
2622         {
2623             update_vi_status(word);
2624         }
2625         return;
2626         break;
2627     case 0x8:
2628         if (vi_register.vi_width != word)
2629         {
2630             update_vi_width(word);
2631         }
2632         return;
2633         break;
2634     case 0x10:
2635         MI_register.mi_intr_reg &= ~0x8;
2636         check_interupt();
2637         return;
2638         break;
2639     }
2640     *readvi[*address_low] = word;
2641 }
2642
2643 void update_vi_status(unsigned int word)
2644 {
2645     vi_register.vi_status = word;
2646     gfx.viStatusChanged();
2647 }
2648
2649 void update_vi_width(unsigned int word)
2650 {
2651     vi_register.vi_width = word;
2652     gfx.viWidthChanged();
2653 }
2654
2655 void write_vib(void)
2656 {
2657     int temp;
2658     switch (*address_low)
2659     {
2660     case 0x0:
2661     case 0x1:
2662     case 0x2:
2663     case 0x3:
2664         temp = vi_register.vi_status;
2665         *((unsigned char*)&temp
2666           + ((*address_low&3)^S8) ) = cpu_byte;
2667         if (vi_register.vi_status != temp)
2668         {
2669             update_vi_status(temp);
2670         }
2671         return;
2672         break;
2673     case 0x8:
2674     case 0x9:
2675     case 0xa:
2676     case 0xb:
2677         temp = vi_register.vi_status;
2678         *((unsigned char*)&temp
2679           + ((*address_low&3)^S8) ) = cpu_byte;
2680         if (vi_register.vi_width != temp)
2681         {
2682             update_vi_width(temp);
2683         }
2684         return;
2685         break;
2686     case 0x10:
2687     case 0x11:
2688     case 0x12:
2689     case 0x13:
2690         MI_register.mi_intr_reg &= ~0x8;
2691         check_interupt();
2692         return;
2693         break;
2694     }
2695     *((unsigned char*)readvi[*address_low & 0xfffc]
2696       + ((*address_low&3)^S8) ) = cpu_byte;
2697 }
2698
2699 void write_vih(void)
2700 {
2701     int temp;
2702     switch (*address_low)
2703     {
2704     case 0x0:
2705     case 0x2:
2706         temp = vi_register.vi_status;
2707         *((unsigned short*)((unsigned char*)&temp
2708                             + ((*address_low&3)^S16) )) = hword;
2709         if (vi_register.vi_status != temp)
2710         {
2711             update_vi_status(temp);
2712         }
2713         return;
2714         break;
2715     case 0x8:
2716     case 0xa:
2717         temp = vi_register.vi_status;
2718         *((unsigned short*)((unsigned char*)&temp
2719                             + ((*address_low&3)^S16) )) = hword;
2720         if (vi_register.vi_width != temp)
2721         {
2722             update_vi_width(temp);
2723         }
2724         return;
2725         break;
2726     case 0x10:
2727     case 0x12:
2728         MI_register.mi_intr_reg &= ~0x8;
2729         check_interupt();
2730         return;
2731         break;
2732     }
2733     *((unsigned short*)((unsigned char*)readvi[*address_low & 0xfffc]
2734                         + ((*address_low&3)^S16) )) = hword;
2735 }
2736
2737 void write_vid(void)
2738 {
2739     switch (*address_low)
2740     {
2741     case 0x0:
2742         if (vi_register.vi_status != dword >> 32)
2743         {
2744             update_vi_status((unsigned int) (dword >> 32));
2745         }
2746         vi_register.vi_origin = (unsigned int) (dword & 0xFFFFFFFF);
2747         return;
2748         break;
2749     case 0x8:
2750         if (vi_register.vi_width != dword >> 32)
2751         {
2752             update_vi_width((unsigned int) (dword >> 32));
2753         }
2754         vi_register.vi_v_intr = (unsigned int) (dword & 0xFFFFFFFF);
2755         return;
2756         break;
2757     case 0x10:
2758         MI_register.mi_intr_reg &= ~0x8;
2759         check_interupt();
2760         vi_register.vi_burst = (unsigned int) (dword & 0xFFFFFFFF);
2761         return;
2762         break;
2763     }
2764     *readvi[*address_low] = (unsigned int) (dword >> 32);
2765     *readvi[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
2766 }
2767
2768 void read_ai(void)
2769 {
2770     switch (*address_low)
2771     {
2772     case 0x4:
2773         update_count();
2774         if (ai_register.current_delay != 0 && get_event(AI_INT) != 0 && (get_event(AI_INT)-Count) < 0x80000000)
2775             *rdword = ((get_event(AI_INT)-Count)*(long long)ai_register.current_len)/
2776                       ai_register.current_delay;
2777         else
2778             *rdword = 0;
2779         return;
2780         break;
2781     }
2782     *rdword = *(readai[*address_low]);
2783 }
2784
2785 void read_aib(void)
2786 {
2787     unsigned int len;
2788     switch (*address_low)
2789     {
2790     case 0x4:
2791     case 0x5:
2792     case 0x6:
2793     case 0x7:
2794         update_count();
2795         if (ai_register.current_delay != 0 && get_event(AI_INT) != 0)
2796             len = (unsigned int) (((get_event(AI_INT) - Count) * (long long)ai_register.current_len) / ai_register.current_delay);
2797         else
2798             len = 0;
2799         *rdword = *((unsigned char*)&len + ((*address_low&3)^S8) );
2800         return;
2801         break;
2802     }
2803     *rdword = *((unsigned char*)readai[*address_low & 0xfffc]
2804                 + ((*address_low&3)^S8) );
2805 }
2806
2807 void read_aih(void)
2808 {
2809     unsigned int len;
2810     switch (*address_low)
2811     {
2812     case 0x4:
2813     case 0x6:
2814         update_count();
2815         if (ai_register.current_delay != 0 && get_event(AI_INT) != 0)
2816             len = (unsigned int) (((get_event(AI_INT)-Count) * (long long)ai_register.current_len) / ai_register.current_delay);
2817         else
2818             len = 0;
2819         *rdword = *((unsigned short*)((unsigned char*)&len
2820                                       + ((*address_low&3)^S16) ));
2821         return;
2822         break;
2823     }
2824     *rdword = *((unsigned short*)((unsigned char*)readai[*address_low & 0xfffc]
2825                                   + ((*address_low&3)^S16) ));
2826 }
2827
2828 void read_aid(void)
2829 {
2830     switch (*address_low)
2831     {
2832     case 0x0:
2833         update_count();
2834         if (ai_register.current_delay != 0 && get_event(AI_INT) != 0)
2835             *rdword = ((get_event(AI_INT)-Count)*(long long)ai_register.current_len)/
2836                       ai_register.current_delay;
2837         else
2838             *rdword = 0;
2839         *rdword |= (unsigned long long)ai_register.ai_dram_addr << 32;
2840         return;
2841         break;
2842     }
2843     *rdword = ((unsigned long long int)(*readai[*address_low])<<32) |
2844               *readai[*address_low+4];
2845 }
2846
2847 void write_ai(void)
2848 {
2849     unsigned int freq,delay=0;
2850     switch (*address_low)
2851     {
2852     case 0x4:
2853         ai_register.ai_len = word;
2854         audio.aiLenChanged();
2855
2856         freq = ROM_PARAMS.aidacrate / (ai_register.ai_dacrate+1);
2857         if (freq)
2858             delay = (unsigned int) (((unsigned long long)ai_register.ai_len*vi_register.vi_delay*ROM_PARAMS.vilimit)/(freq*4));
2859
2860         if (ai_register.ai_status & 0x40000000) // busy
2861         {
2862             ai_register.next_delay = delay;
2863             ai_register.next_len = ai_register.ai_len;
2864             ai_register.ai_status |= 0x80000000;
2865         }
2866         else
2867         {
2868             ai_register.current_delay = delay;
2869             ai_register.current_len = ai_register.ai_len;
2870             update_count();
2871             add_interupt_event(AI_INT, delay);
2872             ai_register.ai_status |= 0x40000000;
2873         }
2874         return;
2875         break;
2876     case 0xc:
2877         MI_register.mi_intr_reg &= ~0x4;
2878         check_interupt();
2879         return;
2880         break;
2881     case 0x10:
2882         if (ai_register.ai_dacrate != word)
2883         {
2884             update_ai_dacrate(word);
2885         }
2886         return;
2887         break;
2888     }
2889     *readai[*address_low] = word;
2890 }
2891
2892 void update_ai_dacrate(unsigned int word)
2893 {
2894     ai_register.ai_dacrate = word;
2895     audio.aiDacrateChanged(ROM_PARAMS.systemtype);
2896 }
2897
2898 void write_aib(void)
2899 {
2900     int temp;
2901     unsigned int delay=0;
2902     switch (*address_low)
2903     {
2904     case 0x4:
2905     case 0x5:
2906     case 0x6:
2907     case 0x7:
2908         temp = ai_register.ai_len;
2909         *((unsigned char*)&temp
2910           + ((*address_low&3)^S8) ) = cpu_byte;
2911         ai_register.ai_len = temp;
2912         audio.aiLenChanged();
2913
2914         delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)*
2915                                     vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate);
2916         //delay = 0;
2917
2918         if (ai_register.ai_status & 0x40000000) // busy
2919         {
2920             ai_register.next_delay = delay;
2921             ai_register.next_len = ai_register.ai_len;
2922             ai_register.ai_status |= 0x80000000;
2923         }
2924         else
2925         {
2926             ai_register.current_delay = delay;
2927             ai_register.current_len = ai_register.ai_len;
2928             update_count();
2929             add_interupt_event(AI_INT, delay/2);
2930             ai_register.ai_status |= 0x40000000;
2931         }
2932         return;
2933         break;
2934     case 0xc:
2935     case 0xd:
2936     case 0xe:
2937     case 0xf:
2938         MI_register.mi_intr_reg &= ~0x4;
2939         check_interupt();
2940         return;
2941         break;
2942     case 0x10:
2943     case 0x11:
2944     case 0x12:
2945     case 0x13:
2946         temp = ai_register.ai_dacrate;
2947         *((unsigned char*)&temp
2948           + ((*address_low&3)^S8) ) = cpu_byte;
2949         if (ai_register.ai_dacrate != temp)
2950         {
2951             update_ai_dacrate(temp);
2952         }
2953         return;
2954         break;
2955     }
2956     *((unsigned char*)readai[*address_low & 0xfffc]
2957       + ((*address_low&3)^S8) ) = cpu_byte;
2958 }
2959
2960 void write_aih(void)
2961 {
2962     int temp;
2963     unsigned int delay=0;
2964     switch (*address_low)
2965     {
2966     case 0x4:
2967     case 0x6:
2968         temp = ai_register.ai_len;
2969         *((unsigned short*)((unsigned char*)&temp
2970                             + ((*address_low&3)^S16) )) = hword;
2971         ai_register.ai_len = temp;
2972         audio.aiLenChanged();
2973
2974         delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)*
2975                                     vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate);
2976
2977         if (ai_register.ai_status & 0x40000000) // busy
2978         {
2979             ai_register.next_delay = delay;
2980             ai_register.next_len = ai_register.ai_len;
2981             ai_register.ai_status |= 0x80000000;
2982         }
2983         else
2984         {
2985             ai_register.current_delay = delay;
2986             ai_register.current_len = ai_register.ai_len;
2987             update_count();
2988             add_interupt_event(AI_INT, delay/2);
2989             ai_register.ai_status |= 0x40000000;
2990         }
2991         return;
2992         break;
2993     case 0xc:
2994     case 0xe:
2995         MI_register.mi_intr_reg &= ~0x4;
2996         check_interupt();
2997         return;
2998         break;
2999     case 0x10:
3000     case 0x12:
3001         temp = ai_register.ai_dacrate;
3002         *((unsigned short*)((unsigned char*)&temp
3003                             + ((*address_low&3)^S16) )) = hword;
3004         if (ai_register.ai_dacrate != temp)
3005         {
3006             update_ai_dacrate(temp);
3007         }
3008         return;
3009         break;
3010     }
3011     *((unsigned short*)((unsigned char*)readai[*address_low & 0xfffc]
3012                         + ((*address_low&3)^S16) )) = hword;
3013 }
3014
3015 void write_aid(void)
3016 {
3017     unsigned int delay=0;
3018     switch (*address_low)
3019     {
3020     case 0x0:
3021         ai_register.ai_dram_addr = (unsigned int) (dword >> 32);
3022         ai_register.ai_len = (unsigned int) (dword & 0xFFFFFFFF);
3023         audio.aiLenChanged();
3024
3025         delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)*
3026                                     vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate);
3027
3028         if (ai_register.ai_status & 0x40000000) // busy
3029         {
3030             ai_register.next_delay = delay;
3031             ai_register.next_len = ai_register.ai_len;
3032             ai_register.ai_status |= 0x80000000;
3033         }
3034         else
3035         {
3036             ai_register.current_delay = delay;
3037             ai_register.current_len = ai_register.ai_len;
3038             update_count();
3039             add_interupt_event(AI_INT, delay/2);
3040             ai_register.ai_status |= 0x40000000;
3041         }
3042         return;
3043         break;
3044     case 0x8:
3045         ai_register.ai_control = (unsigned int) (dword >> 32);
3046         MI_register.mi_intr_reg &= ~0x4;
3047         check_interupt();
3048         return;
3049         break;
3050     case 0x10:
3051         if (ai_register.ai_dacrate != dword >> 32)
3052         {
3053             update_ai_dacrate((unsigned int) (dword >> 32));
3054         }
3055         ai_register.ai_bitrate = (unsigned int) (dword & 0xFFFFFFFF);
3056         return;
3057         break;
3058     }
3059     *readai[*address_low] = (unsigned int) (dword >> 32);
3060     *readai[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
3061 }
3062
3063 void read_pi(void)
3064 {
3065     *rdword = *(readpi[*address_low]);
3066 }
3067
3068 void read_pib(void)
3069 {
3070     *rdword = *((unsigned char*)readpi[*address_low & 0xfffc]
3071                 + ((*address_low&3)^S8) );
3072 }
3073
3074 void read_pih(void)
3075 {
3076     *rdword = *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc]
3077                                   + ((*address_low&3)^S16) ));
3078 }
3079
3080 void read_pid(void)
3081 {
3082     *rdword = ((unsigned long long int)(*readpi[*address_low])<<32) |
3083               *readpi[*address_low+4];
3084 }
3085
3086 void write_pi(void)
3087 {
3088     switch (*address_low)
3089     {
3090     case 0x8:
3091         pi_register.pi_rd_len_reg = word;
3092         dma_pi_read();
3093         return;
3094         break;
3095     case 0xc:
3096         pi_register.pi_wr_len_reg = word;
3097         dma_pi_write();
3098         return;
3099         break;
3100     case 0x10:
3101         if (word & 2) MI_register.mi_intr_reg &= ~0x10;
3102         check_interupt();
3103         return;
3104         break;
3105     case 0x14:
3106     case 0x18:
3107     case 0x1c:
3108     case 0x20:
3109     case 0x24:
3110     case 0x28:
3111     case 0x2c:
3112     case 0x30:
3113         *readpi[*address_low] = word & 0xFF;
3114         return;
3115         break;
3116     }
3117     *readpi[*address_low] = word;
3118 }
3119
3120 void write_pib(void)
3121 {
3122     switch (*address_low)
3123     {
3124     case 0x8:
3125     case 0x9:
3126     case 0xa:
3127     case 0xb:
3128         *((unsigned char*)&pi_register.pi_rd_len_reg
3129           + ((*address_low&3)^S8) ) = cpu_byte;
3130         dma_pi_read();
3131         return;
3132         break;
3133     case 0xc:
3134     case 0xd:
3135     case 0xe:
3136     case 0xf:
3137         *((unsigned char*)&pi_register.pi_wr_len_reg
3138           + ((*address_low&3)^S8) ) = cpu_byte;
3139         dma_pi_write();
3140         return;
3141         break;
3142     case 0x10:
3143     case 0x11:
3144     case 0x12:
3145     case 0x13:
3146         if (word) MI_register.mi_intr_reg &= ~0x10;
3147         check_interupt();
3148         return;
3149         break;
3150     case 0x14:
3151     case 0x15:
3152     case 0x16:
3153     case 0x18:
3154     case 0x19:
3155     case 0x1a:
3156     case 0x1c:
3157     case 0x1d:
3158     case 0x1e:
3159     case 0x20:
3160     case 0x21:
3161     case 0x22:
3162     case 0x24:
3163     case 0x25:
3164     case 0x26:
3165     case 0x28:
3166     case 0x29:
3167     case 0x2a:
3168     case 0x2c:
3169     case 0x2d:
3170     case 0x2e:
3171     case 0x30:
3172     case 0x31:
3173     case 0x32:
3174         return;
3175         break;
3176     }
3177     *((unsigned char*)readpi[*address_low & 0xfffc]
3178       + ((*address_low&3)^S8) ) = cpu_byte;
3179 }
3180
3181 void write_pih(void)
3182 {
3183     switch (*address_low)
3184     {
3185     case 0x8:
3186     case 0xa:
3187         *((unsigned short*)((unsigned char*)&pi_register.pi_rd_len_reg
3188                             + ((*address_low&3)^S16) )) = hword;
3189         dma_pi_read();
3190         return;
3191         break;
3192     case 0xc:
3193     case 0xe:
3194         *((unsigned short*)((unsigned char*)&pi_register.pi_wr_len_reg
3195                             + ((*address_low&3)^S16) )) = hword;
3196         dma_pi_write();
3197         return;
3198         break;
3199     case 0x10:
3200     case 0x12:
3201         if (word) MI_register.mi_intr_reg &= ~0x10;
3202         check_interupt();
3203         return;
3204         break;
3205     case 0x16:
3206     case 0x1a:
3207     case 0x1e:
3208     case 0x22:
3209     case 0x26:
3210     case 0x2a:
3211     case 0x2e:
3212     case 0x32:
3213         *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc]
3214                             + ((*address_low&3)^S16) )) = hword & 0xFF;
3215         return;
3216         break;
3217     case 0x14:
3218     case 0x18:
3219     case 0x1c:
3220     case 0x20:
3221     case 0x24:
3222     case 0x28:
3223     case 0x2c:
3224     case 0x30:
3225         return;
3226         break;
3227     }
3228     *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc]
3229                         + ((*address_low&3)^S16) )) = hword;
3230 }
3231
3232 void write_pid(void)
3233 {
3234     switch (*address_low)
3235     {
3236     case 0x8:
3237         pi_register.pi_rd_len_reg = (unsigned int) (dword >> 32);
3238         dma_pi_read();
3239         pi_register.pi_wr_len_reg = (unsigned int) (dword & 0xFFFFFFFF);
3240         dma_pi_write();
3241         return;
3242         break;
3243     case 0x10:
3244         if (word) MI_register.mi_intr_reg &= ~0x10;
3245         check_interupt();
3246         *readpi[*address_low+4] = (unsigned int) (dword & 0xFF);
3247         return;
3248         break;
3249     case 0x18:
3250     case 0x20:
3251     case 0x28:
3252     case 0x30:
3253         *readpi[*address_low] = (unsigned int) (dword >> 32) & 0xFF;
3254         *readpi[*address_low+4] = (unsigned int) (dword & 0xFF);
3255         return;
3256         break;
3257     }
3258     *readpi[*address_low] = (unsigned int) (dword >> 32);
3259     *readpi[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
3260 }
3261
3262 void read_ri(void)
3263 {
3264     *rdword = *(readri[*address_low]);
3265 }
3266
3267 void read_rib(void)
3268 {
3269     *rdword = *((unsigned char*)readri[*address_low & 0xfffc]
3270                 + ((*address_low&3)^S8) );
3271 }
3272
3273 void read_rih(void)
3274 {
3275     *rdword = *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
3276                                   + ((*address_low&3)^S16) ));
3277 }
3278
3279 void read_rid(void)
3280 {
3281     *rdword = ((unsigned long long int)(*readri[*address_low])<<32) |
3282               *readri[*address_low+4];
3283 }
3284
3285 void write_ri(void)
3286 {
3287     *readri[*address_low] = word;
3288 }
3289
3290 void write_rib(void)
3291 {
3292     *((unsigned char*)readri[*address_low & 0xfffc]
3293       + ((*address_low&3)^S8) ) = cpu_byte;
3294 }
3295
3296 void write_rih(void)
3297 {
3298     *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
3299                         + ((*address_low&3)^S16) )) = hword;
3300 }
3301
3302 void write_rid(void)
3303 {
3304     *readri[*address_low] = (unsigned int) (dword >> 32);
3305     *readri[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
3306 }
3307
3308 void read_si(void)
3309 {
3310     *rdword = *(readsi[*address_low]);
3311 }
3312
3313 void read_sib(void)
3314 {
3315     *rdword = *((unsigned char*)readsi[*address_low & 0xfffc]
3316                 + ((*address_low&3)^S8) );
3317 }
3318
3319 void read_sih(void)
3320 {
3321     *rdword = *((unsigned short*)((unsigned char*)readsi[*address_low & 0xfffc]
3322                                   + ((*address_low&3)^S16) ));
3323 }
3324
3325 void read_sid(void)
3326 {
3327     *rdword = ((unsigned long long int)(*readsi[*address_low])<<32) |
3328               *readsi[*address_low+4];
3329 }
3330
3331 void write_si(void)
3332 {
3333     switch (*address_low)
3334     {
3335     case 0x0:
3336         si_register.si_dram_addr = word;
3337         return;
3338         break;
3339     case 0x4:
3340         si_register.si_pif_addr_rd64b = word;
3341         dma_si_read();
3342         return;
3343         break;
3344     case 0x10:
3345         si_register.si_pif_addr_wr64b = word;
3346         dma_si_write();
3347         return;
3348         break;
3349     case 0x18:
3350         MI_register.mi_intr_reg &= ~0x2;
3351         si_register.si_stat &= ~0x1000;
3352         check_interupt();
3353         return;
3354         break;
3355     }
3356 }
3357
3358 void write_sib(void)
3359 {
3360     switch (*address_low)
3361     {
3362     case 0x0:
3363     case 0x1:
3364     case 0x2:
3365     case 0x3:
3366         *((unsigned char*)&si_register.si_dram_addr
3367           + ((*address_low&3)^S8) ) = cpu_byte;
3368         return;
3369         break;
3370     case 0x4:
3371     case 0x5:
3372     case 0x6:
3373     case 0x7:
3374         *((unsigned char*)&si_register.si_pif_addr_rd64b
3375           + ((*address_low&3)^S8) ) = cpu_byte;
3376         dma_si_read();
3377         return;
3378         break;
3379     case 0x10:
3380     case 0x11:
3381     case 0x12:
3382     case 0x13:
3383         *((unsigned char*)&si_register.si_pif_addr_wr64b
3384           + ((*address_low&3)^S8) ) = cpu_byte;
3385         dma_si_write();
3386         return;
3387         break;
3388     case 0x18:
3389     case 0x19:
3390     case 0x1a:
3391     case 0x1b:
3392         MI_register.mi_intr_reg &= ~0x2;
3393         si_register.si_stat &= ~0x1000;
3394         check_interupt();
3395         return;
3396         break;
3397     }
3398 }
3399
3400 void write_sih(void)
3401 {
3402     switch (*address_low)
3403     {
3404     case 0x0:
3405     case 0x2:
3406         *((unsigned short*)((unsigned char*)&si_register.si_dram_addr
3407                             + ((*address_low&3)^S16) )) = hword;
3408         return;
3409         break;
3410     case 0x4:
3411     case 0x6:
3412         *((unsigned short*)((unsigned char*)&si_register.si_pif_addr_rd64b
3413                             + ((*address_low&3)^S16) )) = hword;
3414         dma_si_read();
3415         return;
3416         break;
3417     case 0x10:
3418     case 0x12:
3419         *((unsigned short*)((unsigned char*)&si_register.si_pif_addr_wr64b
3420                             + ((*address_low&3)^S16) )) = hword;
3421         dma_si_write();
3422         return;
3423         break;
3424     case 0x18:
3425     case 0x1a:
3426         MI_register.mi_intr_reg &= ~0x2;
3427         si_register.si_stat &= ~0x1000;
3428         check_interupt();
3429         return;
3430         break;
3431     }
3432 }
3433
3434 void write_sid(void)
3435 {
3436     switch (*address_low)
3437     {
3438     case 0x0:
3439         si_register.si_dram_addr = (unsigned int) (dword >> 32);
3440         si_register.si_pif_addr_rd64b = (unsigned int) (dword & 0xFFFFFFFF);
3441         dma_si_read();
3442         return;
3443         break;
3444     case 0x10:
3445         si_register.si_pif_addr_wr64b = (unsigned int) (dword >> 32);
3446         dma_si_write();
3447         return;
3448         break;
3449     case 0x18:
3450         MI_register.mi_intr_reg &= ~0x2;
3451         si_register.si_stat &= ~0x1000;
3452         check_interupt();
3453         return;
3454         break;
3455     }
3456 }
3457
3458 void read_flashram_status(void)
3459 {
3460     if (flashram_info.use_flashram != -1 && *address_low == 0)
3461     {
3462         *rdword = flashram_status();
3463         flashram_info.use_flashram = 1;
3464     }
3465     else
3466         DebugMessage(M64MSG_ERROR, "unknown read in read_flashram_status()");
3467 }
3468
3469 void read_flashram_statusb(void)
3470 {
3471     DebugMessage(M64MSG_ERROR, "read_flashram_statusb() not implemented");
3472 }
3473
3474 void read_flashram_statush(void)
3475 {
3476     DebugMessage(M64MSG_ERROR, "read_flashram_statush() not implemented");
3477 }
3478
3479 void read_flashram_statusd(void)
3480 {
3481     DebugMessage(M64MSG_ERROR, "read_flashram_statusd() not implemented");
3482 }
3483
3484 void write_flashram_dummy(void)
3485 {
3486 }
3487
3488 void write_flashram_dummyb(void)
3489 {
3490 }
3491
3492 void write_flashram_dummyh(void)
3493 {
3494 }
3495
3496 void write_flashram_dummyd(void)
3497 {
3498 }
3499
3500 void write_flashram_command(void)
3501 {
3502     if (flashram_info.use_flashram != -1 && *address_low == 0)
3503     {
3504         flashram_command(word);
3505         flashram_info.use_flashram = 1;
3506     }
3507     else
3508         DebugMessage(M64MSG_ERROR, "unknown write in write_flashram_command()");
3509 }
3510
3511 void write_flashram_commandb(void)
3512 {
3513     DebugMessage(M64MSG_ERROR, "write_flashram_commandb() not implemented");
3514 }
3515
3516 void write_flashram_commandh(void)
3517 {
3518     DebugMessage(M64MSG_ERROR, "write_flashram_commandh() not implemented");
3519 }
3520
3521 void write_flashram_commandd(void)
3522 {
3523     DebugMessage(M64MSG_ERROR, "write_flashram_commandd() not implemented");
3524 }
3525
3526 static unsigned int lastwrite = 0;
3527
3528 void read_rom(void)
3529 {
3530     if (lastwrite)
3531     {
3532         *rdword = lastwrite;
3533         lastwrite = 0;
3534     }
3535     else
3536         *rdword = *((unsigned int *)(rom + (address & 0x03FFFFFF)));
3537 }
3538
3539 void read_romb(void)
3540 {
3541     *rdword = *(rom + ((address^S8) & 0x03FFFFFF));
3542 }
3543
3544 void read_romh(void)
3545 {
3546     *rdword = *((unsigned short *)(rom + ((address^S16) & 0x03FFFFFF)));
3547 }
3548
3549 void read_romd(void)
3550 {
3551     *rdword = ((unsigned long long)(*((unsigned int *)(rom+(address&0x03FFFFFF))))<<32)|
3552               *((unsigned int *)(rom + ((address+4)&0x03FFFFFF)));
3553 }
3554
3555 void write_rom(void)
3556 {
3557     lastwrite = word;
3558 }
3559
3560 void read_pif(void)
3561 {
3562     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3563     {
3564         DebugMessage(M64MSG_ERROR, "reading a word in PIF at invalid address 0x%x", address);
3565         *rdword = 0;
3566         return;
3567     }
3568
3569     *rdword = sl(*((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)));
3570 }
3571
3572 void read_pifb(void)
3573 {
3574     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3575     {
3576         DebugMessage(M64MSG_ERROR, "reading a byte in PIF at invalid address 0x%x", address);
3577         *rdword = 0;
3578         return;
3579     }
3580
3581     *rdword = *(PIF_RAMb + ((address & 0x7FF) - 0x7C0));
3582 }
3583
3584 void read_pifh(void)
3585 {
3586     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3587     {
3588         DebugMessage(M64MSG_ERROR, "reading a hword in PIF at invalid address 0x%x", address);
3589         *rdword = 0;
3590         return;
3591     }
3592
3593     *rdword = (*(PIF_RAMb + ((address & 0x7FF) - 0x7C0)) << 8) |
3594               *(PIF_RAMb + (((address+1) & 0x7FF) - 0x7C0));
3595 }
3596
3597 void read_pifd(void)
3598 {
3599     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3600     {
3601         DebugMessage(M64MSG_ERROR, "reading a double word in PIF in invalid address 0x%x", address);
3602         *rdword = 0;
3603         return;
3604     }
3605
3606     *rdword = ((unsigned long long)sl(*((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0))) << 32)|
3607               sl(*((unsigned int *)(PIF_RAMb + ((address+4) & 0x7FF) - 0x7C0)));
3608 }
3609
3610 void write_pif(void)
3611 {
3612     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3613     {
3614         DebugMessage(M64MSG_ERROR, "writing a word in PIF at invalid address 0x%x", address);
3615         return;
3616     }
3617
3618     *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) = sl(word);
3619     if ((address & 0x7FF) == 0x7FC)
3620     {
3621         if (PIF_RAMb[0x3F] == 0x08)
3622         {
3623             PIF_RAMb[0x3F] = 0;
3624             update_count();
3625             add_interupt_event(SI_INT, /*0x100*/0x900);
3626         }
3627         else
3628             update_pif_write();
3629     }
3630 }
3631
3632 void write_pifb(void)
3633 {
3634     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3635     {
3636         DebugMessage(M64MSG_ERROR, "writing a byte in PIF at invalid address 0x%x", address);
3637         return;
3638     }
3639
3640     *(PIF_RAMb + (address & 0x7FF) - 0x7C0) = cpu_byte;
3641     if ((address & 0x7FF) == 0x7FF)
3642     {
3643         if (PIF_RAMb[0x3F] == 0x08)
3644         {
3645             PIF_RAMb[0x3F] = 0;
3646             update_count();
3647             add_interupt_event(SI_INT, /*0x100*/0x900);
3648         }
3649         else
3650             update_pif_write();
3651     }
3652 }
3653
3654 void write_pifh(void)
3655 {
3656     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3657     {
3658         DebugMessage(M64MSG_ERROR, "writing a hword in PIF at invalid address 0x%x", address);
3659         return;
3660     }
3661
3662     *(PIF_RAMb + (address & 0x7FF) - 0x7C0) = hword >> 8;
3663     *(PIF_RAMb + ((address+1) & 0x7FF) - 0x7C0) = hword & 0xFF;
3664     if ((address & 0x7FF) == 0x7FE)
3665     {
3666         if (PIF_RAMb[0x3F] == 0x08)
3667         {
3668             PIF_RAMb[0x3F] = 0;
3669             update_count();
3670             add_interupt_event(SI_INT, /*0x100*/0x900);
3671         }
3672         else
3673             update_pif_write();
3674     }
3675 }
3676
3677 void write_pifd(void)
3678 {
3679     if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
3680     {
3681         DebugMessage(M64MSG_ERROR, "writing a double word in PIF at 0x%x", address);
3682         return;
3683     }
3684
3685     *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) =
3686         sl((unsigned int)(dword >> 32));
3687     *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) =
3688         sl((unsigned int)(dword & 0xFFFFFFFF));
3689     if ((address & 0x7FF) == 0x7F8)
3690     {
3691         if (PIF_RAMb[0x3F] == 0x08)
3692         {
3693             PIF_RAMb[0x3F] = 0;
3694             update_count();
3695             add_interupt_event(SI_INT, /*0x100*/0x900);
3696         }
3697         else
3698             update_pif_write();
3699     }
3700 }
3701
3702 unsigned int *fast_mem_access(unsigned int address)
3703 {
3704     /* This code is performance critical, specially on pure interpreter mode.
3705      * Removing error checking saves some time, but the emulator may crash. */
3706     if (address < 0x80000000 || address >= 0xc0000000)
3707         address = virtual_to_physical_address(address, 2);
3708
3709     if ((address & 0x1FFFFFFF) >= 0x10000000)
3710         return (unsigned int *)rom + ((address & 0x1FFFFFFF) - 0x10000000)/4;
3711     else if ((address & 0x1FFFFFFF) < 0x800000)
3712         return (unsigned int *)rdram + (address & 0x1FFFFFFF)/4;
3713     else if (address >= 0xa4000000 && address <= 0xa4001000)
3714         return (unsigned int *)SP_DMEM + (address & 0xFFF)/4;
3715     else if ((address >= 0xa4001000 && address <= 0xa4002000))
3716         return (unsigned int *)SP_IMEM + (address & 0xFFF)/4;
3717     else
3718         return NULL;
3719 }