ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interupt.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - interupt.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 <SDL.h>
25
26 #define M64P_CORE_PROTOTYPES 1
27 #include "api/m64p_types.h"
28 #include "api/callbacks.h"
29 #include "api/m64p_vidext.h"
30 #include "api/vidext.h"
31 #include "memory/memory.h"
32 #include "main/rom.h"
33 #include "main/main.h"
34 #include "main/savestates.h"
35 #include "main/cheat.h"
36 #include "osd/osd.h"
37 #include "plugin/plugin.h"
38
39 #include "interupt.h"
40 #include "r4300.h"
41 #include "macros.h"
42 #include "exception.h"
43 #include "reset.h"
44 #include "new_dynarec/new_dynarec.h"
45
46 #ifdef WITH_LIRC
47 #include "main/lirc.h"
48 #endif
49
50 unsigned int next_vi;
51 int vi_field=0;
52 static int vi_counter=0;
53
54 int interupt_unsafe_state = 0;
55
56 typedef struct _interupt_queue
57 {
58    int type;
59    unsigned int count;
60    struct _interupt_queue *next;
61 } interupt_queue;
62
63 static interupt_queue *q = NULL;
64
65 static void clear_queue(void)
66 {
67     while(q != NULL)
68     {
69         interupt_queue *aux = q->next;
70         free(q);
71         q = aux;
72     }
73 }
74
75 /*static void print_queue(void)
76 {
77     interupt_queue *aux;
78     //if (Count < 0x7000000) return;
79     DebugMessage(M64MSG_INFO, "------------------ 0x%x", (unsigned int)Count);
80     aux = q;
81     while (aux != NULL)
82     {
83         DebugMessage(M64MSG_INFO, "Count:%x, %x", (unsigned int)aux->count, aux->type);
84         aux = aux->next;
85     }
86 }*/
87
88 static int SPECIAL_done = 0;
89
90 static int before_event(unsigned int evt1, unsigned int evt2, int type2)
91 {
92     if(evt1 - Count < 0x80000000)
93     {
94         if(evt2 - Count < 0x80000000)
95         {
96             if((evt1 - Count) < (evt2 - Count)) return 1;
97             else return 0;
98         }
99         else
100         {
101             if((Count - evt2) < 0x10000000)
102             {
103                 switch(type2)
104                 {
105                     case SPECIAL_INT:
106                         if(SPECIAL_done) return 1;
107                         else return 0;
108                         break;
109                     default:
110                         return 0;
111                 }
112             }
113             else return 1;
114         }
115     }
116     else return 0;
117 }
118
119 void add_interupt_event(int type, unsigned int delay)
120 {
121     unsigned int count = Count + delay/**2*/;
122     int special = 0;
123     interupt_queue *aux = q;
124    
125     if(type == SPECIAL_INT /*|| type == COMPARE_INT*/) special = 1;
126     if(Count > 0x80000000) SPECIAL_done = 0;
127    
128     if (get_event(type)) {
129         //DebugMessage(M64MSG_WARNING, "two events of type 0x%x in interrupt queue", type);
130                 return; // silently return...
131     }
132    
133     if (q == NULL)
134     {
135         q = (interupt_queue *) malloc(sizeof(interupt_queue));
136         q->next = NULL;
137         q->count = count;
138         q->type = type;
139         next_interupt = q->count;
140         //print_queue();
141         return;
142     }
143    
144     if(before_event(count, q->count, q->type) && !special)
145     {
146         q = (interupt_queue *) malloc(sizeof(interupt_queue));
147         q->next = aux;
148         q->count = count;
149         q->type = type;
150         next_interupt = q->count;
151         //print_queue();
152         return;
153     }
154    
155     while (aux->next != NULL && (!before_event(count, aux->next->count, aux->next->type) || special))
156         aux = aux->next;
157    
158     if (aux->next == NULL)
159     {
160         aux->next = (interupt_queue *) malloc(sizeof(interupt_queue));
161         aux = aux->next;
162         aux->next = NULL;
163         aux->count = count;
164         aux->type = type;
165     }
166     else
167     {
168         interupt_queue *aux2;
169         if (type != SPECIAL_INT)
170             while(aux->next != NULL && aux->next->count == count)
171                 aux = aux->next;
172         aux2 = aux->next;
173         aux->next = (interupt_queue *) malloc(sizeof(interupt_queue));
174         aux = aux->next;
175         aux->next = aux2;
176         aux->count = count;
177         aux->type = type;
178     }
179 }
180
181 void add_interupt_event_count(int type, unsigned int count)
182 {
183     add_interupt_event(type, (count - Count)/*/2*/);
184 }
185
186 static void remove_interupt_event(void)
187 {
188     interupt_queue *aux = q->next;
189     if(q->type == SPECIAL_INT) SPECIAL_done = 1;
190     free(q);
191     q = aux;
192     if (q != NULL && (q->count > Count || (Count - q->count) < 0x80000000))
193         next_interupt = q->count;
194     else
195         next_interupt = 0;
196 }
197
198 unsigned int get_event(int type)
199 {
200     interupt_queue *aux = q;
201     if (q == NULL) return 0;
202     if (q->type == type)
203         return q->count;
204     while (aux->next != NULL && aux->next->type != type)
205         aux = aux->next;
206     if (aux->next != NULL)
207         return aux->next->count;
208     return 0;
209 }
210
211 int get_next_event_type(void)
212 {
213     if (q == NULL) return 0;
214     return q->type;
215 }
216
217 void remove_event(int type)
218 {
219     interupt_queue *aux = q;
220     if (q == NULL) return;
221     if (q->type == type)
222     {
223         aux = aux->next;
224         free(q);
225         q = aux;
226         return;
227     }
228     while (aux->next != NULL && aux->next->type != type)
229         aux = aux->next;
230     if (aux->next != NULL) // it's a type int
231     {
232         interupt_queue *aux2 = aux->next->next;
233         free(aux->next);
234         aux->next = aux2;
235     }
236 }
237
238 void translate_event_queue(unsigned int base)
239 {
240     interupt_queue *aux;
241     remove_event(COMPARE_INT);
242     remove_event(SPECIAL_INT);
243     aux=q;
244     while (aux != NULL)
245     {
246         aux->count = (aux->count - Count)+base;
247         aux = aux->next;
248     }
249     add_interupt_event_count(COMPARE_INT, Compare);
250     add_interupt_event_count(SPECIAL_INT, 0);
251 }
252
253 int save_eventqueue_infos(char *buf)
254 {
255     int len = 0;
256     interupt_queue *aux = q;
257     if (q == NULL)
258     {
259         *((unsigned int*)&buf[0]) = 0xFFFFFFFF;
260         return 4;
261     }
262     while (aux != NULL)
263     {
264         memcpy(buf+len  , &aux->type , 4);
265         memcpy(buf+len+4, &aux->count, 4);
266         len += 8;
267         aux = aux->next;
268     }
269     *((unsigned int*)&buf[len]) = 0xFFFFFFFF;
270     return len+4;
271 }
272
273 void load_eventqueue_infos(char *buf)
274 {
275     int len = 0;
276     clear_queue();
277     while (*((unsigned int*)&buf[len]) != 0xFFFFFFFF)
278     {
279         int type = *((unsigned int*)&buf[len]);
280         unsigned int count = *((unsigned int*)&buf[len+4]);
281         add_interupt_event_count(type, count);
282         len += 8;
283     }
284 }
285
286 void init_interupt(void)
287 {
288     SPECIAL_done = 1;
289     next_vi = next_interupt = 5000;
290     vi_register.vi_delay = next_vi;
291     vi_field = 0;
292     clear_queue();
293     add_interupt_event_count(VI_INT, next_vi);
294     add_interupt_event_count(SPECIAL_INT, 0);
295 }
296
297 void check_interupt(void)
298 {
299     if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
300         Cause = (Cause | 0x400) & 0xFFFFFF83;
301     else
302         Cause &= ~0x400;
303     if ((Status & 7) != 1) return;
304     if (Status & Cause & 0xFF00)
305     {
306         if(q == NULL)
307         {
308             q = (interupt_queue *) malloc(sizeof(interupt_queue));
309             q->next = NULL;
310             q->count = Count;
311             q->type = CHECK_INT;
312         }
313         else
314         {
315             interupt_queue* aux = (interupt_queue *) malloc(sizeof(interupt_queue));
316             aux->next = q;
317             aux->count = Count;
318             aux->type = CHECK_INT;
319             q = aux;
320         }
321         next_interupt = Count;
322     }
323 }
324
325 void gen_interupt(void)
326 {
327     if (stop == 1)
328     {
329         vi_counter = 0; // debug
330         dyna_stop();
331     }
332
333     if (!interupt_unsafe_state)
334     {
335         if (savestates_get_job() == savestates_job_load)
336         {
337             savestates_load();
338             return;
339         }
340
341         if (reset_hard_job)
342         {
343             reset_hard();
344             reset_hard_job = 0;
345             return;
346         }
347     }
348    
349     if (skip_jump)
350     {
351         unsigned int dest = skip_jump;
352         skip_jump = 0;
353
354         if (q->count > Count || (Count - q->count) < 0x80000000)
355             next_interupt = q->count;
356         else
357             next_interupt = 0;
358         
359         last_addr = dest;
360         generic_jump_to(dest);
361         return;
362     } 
363
364     switch(q->type)
365     {
366         case SPECIAL_INT:
367             if (Count > 0x10000000) return;
368             remove_interupt_event();
369             add_interupt_event_count(SPECIAL_INT, 0);
370             return;
371             break;
372         case VI_INT:
373             if(vi_counter < 60)
374             {
375                 if (vi_counter == 0)
376                     cheat_apply_cheats(ENTRY_BOOT);
377                 vi_counter++;
378             }
379             else
380             {
381                 cheat_apply_cheats(ENTRY_VI);
382             }
383             gfx.updateScreen();
384 #ifdef WITH_LIRC
385             lircCheckInput();
386 #endif
387             SDL_PumpEvents();
388
389             refresh_stat();
390
391             // if paused, poll for input events
392             if(rompause)
393             {
394                 osd_render();  // draw Paused message in case gfx.updateScreen didn't do it
395                 VidExt_GL_SwapBuffers();
396                 while(rompause)
397                 {
398                     SDL_Delay(10);
399                     SDL_PumpEvents();
400 #ifdef WITH_LIRC
401                     lircCheckInput();
402 #endif //WITH_LIRC
403                 }
404             }
405
406             new_vi();
407             if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
408             else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
409             next_vi += vi_register.vi_delay;
410             if (vi_register.vi_status&0x40) vi_field=1-vi_field;
411             else vi_field=0;
412
413             remove_interupt_event();
414             add_interupt_event_count(VI_INT, next_vi);
415     
416             MI_register.mi_intr_reg |= 0x08;
417             if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
418                 Cause = (Cause | 0x400) & 0xFFFFFF83;
419             else
420                 return;
421             if ((Status & 7) != 1) return;
422             if (!(Status & Cause & 0xFF00)) return;
423             break;
424     
425         case COMPARE_INT:
426             remove_interupt_event();
427             Count+=count_per_op;
428             add_interupt_event_count(COMPARE_INT, Compare);
429             Count-=count_per_op;
430     
431             Cause = (Cause | 0x8000) & 0xFFFFFF83;
432             if ((Status & 7) != 1) return;
433             if (!(Status & Cause & 0xFF00)) return;
434             break;
435     
436         case CHECK_INT:
437             remove_interupt_event();
438             break;
439     
440         case SI_INT:
441 #ifdef WITH_LIRC
442             lircCheckInput();
443 #endif //WITH_LIRC
444             SDL_PumpEvents();
445             PIF_RAMb[0x3F] = 0x0;
446             remove_interupt_event();
447             MI_register.mi_intr_reg |= 0x02;
448             si_register.si_stat |= 0x1000;
449             if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
450                 Cause = (Cause | 0x400) & 0xFFFFFF83;
451             else
452                 return;
453             if ((Status & 7) != 1) return;
454             if (!(Status & Cause & 0xFF00)) return;
455             break;
456     
457         case PI_INT:
458             remove_interupt_event();
459             MI_register.mi_intr_reg |= 0x10;
460             pi_register.read_pi_status_reg &= ~3;
461             if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
462                 Cause = (Cause | 0x400) & 0xFFFFFF83;
463             else
464                 return;
465             if ((Status & 7) != 1) return;
466             if (!(Status & Cause & 0xFF00)) return;
467             break;
468     
469         case AI_INT:
470             if (ai_register.ai_status & 0x80000000) // full
471             {
472                 unsigned int ai_event = get_event(AI_INT);
473                 remove_interupt_event();
474                 ai_register.ai_status &= ~0x80000000;
475                 ai_register.current_delay = ai_register.next_delay;
476                 ai_register.current_len = ai_register.next_len;
477                 add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
478          
479                 MI_register.mi_intr_reg |= 0x04;
480                 if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
481                     Cause = (Cause | 0x400) & 0xFFFFFF83;
482                 else
483                     return;
484                 if ((Status & 7) != 1) return;
485                 if (!(Status & Cause & 0xFF00)) return;
486             }
487             else
488             {
489                 remove_interupt_event();
490                 ai_register.ai_status &= ~0x40000000;
491
492                 //-------
493                 MI_register.mi_intr_reg |= 0x04;
494                 if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
495                     Cause = (Cause | 0x400) & 0xFFFFFF83;
496                 else
497                     return;
498                 if ((Status & 7) != 1) return;
499                 if (!(Status & Cause & 0xFF00)) return;
500             }
501             break;
502
503         case SP_INT:
504             remove_interupt_event();
505             sp_register.sp_status_reg |= 0x203;
506             // sp_register.sp_status_reg |= 0x303;
507     
508             if (!(sp_register.sp_status_reg & 0x40)) return; // !intr_on_break
509             MI_register.mi_intr_reg |= 0x01;
510             if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
511                 Cause = (Cause | 0x400) & 0xFFFFFF83;
512             else
513                 return;
514             if ((Status & 7) != 1) return;
515             if (!(Status & Cause & 0xFF00)) return;
516             break;
517     
518         case DP_INT:
519             remove_interupt_event();
520             dpc_register.dpc_status &= ~2;
521             dpc_register.dpc_status |= 0x81;
522             MI_register.mi_intr_reg |= 0x20;
523             if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
524                 Cause = (Cause | 0x400) & 0xFFFFFF83;
525             else
526                 return;
527             if ((Status & 7) != 1) return;
528             if (!(Status & Cause & 0xFF00)) return;
529             break;
530
531         case HW2_INT:
532             // Hardware Interrupt 2 -- remove interrupt event from queue
533             remove_interupt_event();
534             // setup r4300 Status flags: reset TS, and SR, set IM2
535             Status = (Status & ~0x00380000) | 0x1000;
536             Cause = (Cause | 0x1000) & 0xFFFFFF83;
537             /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the
538              * interpreter or dynarec
539              */
540             break;
541
542         case NMI_INT:
543             // Non Maskable Interrupt -- remove interrupt event from queue
544             remove_interupt_event();
545             // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR
546             Status = (Status & ~0x00380000) | 0x00500004;
547             Cause  = 0x00000000;
548             // simulate the soft reset code which would run from the PIF ROM
549             r4300_reset_soft();
550             // clear all interrupts, reset interrupt counters back to 0
551             Count = 0;
552             vi_counter = 0;
553             init_interupt();
554             // clear the audio status register so that subsequent write_ai() calls will work properly
555             ai_register.ai_status = 0;
556             // set ErrorEPC with the last instruction address
557             ErrorEPC = PC->addr;
558             // reset the r4300 internal state
559             if (r4300emu != CORE_PURE_INTERPRETER)
560             {
561                 // clear all the compiled instruction blocks and re-initialize
562                 free_blocks();
563                 init_blocks();
564             }
565             // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags
566             if(delay_slot==1 || delay_slot==3)
567             {
568                 ErrorEPC-=4;
569             }
570             delay_slot = 0;
571             dyna_interp = 0;
572             // set next instruction address to reset vector
573             last_addr = 0xa4000040;
574             generic_jump_to(0xa4000040);
575             return;
576
577         default:
578             DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q->type);
579             remove_interupt_event();
580             break;
581     }
582
583 #ifdef NEW_DYNAREC
584     if (r4300emu == CORE_DYNAREC) {
585         EPC = pcaddr;
586         pcaddr = 0x80000180;
587         Status |= 2;
588         Cause &= 0x7FFFFFFF;
589         pending_exception=1;
590     } else {
591         exception_general();
592     }
593 #else
594     exception_general();
595 #endif
596
597     if (!interupt_unsafe_state)
598     {
599         if (savestates_get_job() == savestates_job_save)
600         {
601             savestates_save();
602             return;
603         }
604     }
605 }
606