1
2 /*
3 * O2EM Free Odyssey2 / Videopac+ Emulator
4 *
5 * Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
6 *
7 * Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
8 * Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
9 *
10 * http://o2em.sourceforge.net
11 *
12 *
13 *
14 * Main O2 machine emulation
15 */
16
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <time.h>
21 #include "audio.h"
22 #include "types.h"
23 #include "cpu.h"
24 #include "keyboard.h"
25 #include "config.h"
26 #include "debug.h"
27 #include "vdc.h"
28 #include "vpp.h"
29 #include "timefunc.h"
30 #include "voice.h"
31 #include "vmachine.h"
32 #include "allegro.h"
33
34
35
36 static Byte x_latch,y_latch;
37 static int romlatch=0;
38 static Byte line_count;
39 static int fps=FPS_NTSC;
40
41 static Byte snapedlines[MAXLINES+2*MAXSNAP][256][2];
42
43 int evblclk=EVBLCLK_NTSC;
44
45 struct resource app_data;
46 int frame=0;
47 Byte dbstick1,dbstick2;
48
49 int int_clk; /* counter for length of /INT pulses */
50 int master_clk; /* Master clock */
51 int h_clk; /* horizontal clock */
52 unsigned long clk_counter;
53 int last_line;
54 int key2vcnt=0;
55 int mstate;
56
57 int pendirq=0;
58 int enahirq=1;
59 int useforen=0;
60 long regionoff=0xffff;
61 int mxsnap=2;
62 int sproff=0;
63 int tweakedaudio=0;
64
65 Byte rom_table[8][4096];
66
67 Byte intRAM[64];
68 Byte extRAM[256];
69 Byte extROM[1024];
70 Byte VDCwrite[256];
71 Byte ColorVector[MAXLINES];
72 Byte AudioVector[MAXLINES];
73 Byte *rom;
74
75 int key2[128];
76
77
78 static unsigned int key_map[6][8]= {
79 {KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7},
80 {KEY_8,KEY_9,0,0,KEY_SPACE,KEY_SLASH,KEY_L,KEY_P},
81 {KEY_PLUS_PAD,KEY_W,KEY_E,KEY_R,KEY_T,KEY_U,KEY_I,KEY_O},
82 {KEY_Q,KEY_S,KEY_D,KEY_F,KEY_G,KEY_H,KEY_J,KEY_K},
83 {KEY_A,KEY_Z,KEY_X,KEY_C,KEY_V,KEY_B,KEY_M,KEY_STOP},
84 {KEY_MINUS,KEY_ASTERISK,KEY_SLASH_PAD,KEY_EQUALS,KEY_Y,KEY_N,KEY_DEL,KEY_ENTER}
85 };
86
87
88 static void do_kluges(void);
89 static void setvideomode(int t);
90
run(void)91 void run(void){
92 while(!key_done) {
93
94 if (key_debug) {
95 app_data.debug=1;
96 set_textmode();
97 mute_audio();
98 mute_voice();
99 debug();
100 grmode();
101 app_data.debug=0;
102 init_keyboard();
103 init_sound_stream();
104 }
105
106 cpu_exec();
107
108 }
109 close_audio();
110 close_voice();
111 close_display();
112 }
113
114
handle_vbl(void)115 void handle_vbl(void){
116 if (!app_data.debug) {
117 handle_key();
118 update_audio();
119 update_voice();
120 }
121 draw_region();
122 ext_IRQ();
123 mstate = 1;
124 }
125
126
handle_evbl(void)127 void handle_evbl(void){
128 static long last=0;
129 static int rest_cnt=0;
130 int i;
131
132 #ifndef ALLEGRO_DOS
133 yield_timeslice();
134 #endif
135 i = (15*app_data.speed/100);
136 rest_cnt = (rest_cnt+1)%(i<5?5:i);
137 #ifdef ALLEGRO_WINDOWS
138 if (rest_cnt==0) rest(1);
139 #endif
140 last_line=0;
141 master_clk -= evblclk;
142 frame++;
143 if (!app_data.debug) {
144 finish_display();
145 }
146
147 if (app_data.crc == 0xA7344D1F)
148 {for (i=0; i<140; i++)
149 {
150 ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
151 AudioVector[i] = VDCwrite[0xAA];
152 }
153 }/*Atlantis*/
154 else
155 for (i=0; i<MAXLINES; i++) {
156 ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
157 AudioVector[i] = VDCwrite[0xAA];
158 }
159
160
161 if (key2vcnt++ > 10) {
162 key2vcnt=0;
163 for (i=0; i<128; i++) key2[i] = 0;
164 dbstick1 = dbstick2 = 0;
165 }
166 if (app_data.limit) {
167 long d,f;
168 d = (TICKSPERSEC*100)/(app_data.speed*fps);
169 f = ((d-gettimeticks()+last)*1000)/TICKSPERSEC;
170 if (f>0) {
171 #ifdef ALLEGRO_WINDOWS
172 f = f-(f%10);
173 if (f>5) rest(f-5);
174 #else
175 #ifndef ALLEGRO_DOS
176 yield_timeslice();
177 #endif
178 #endif
179 }
180 while (gettimeticks() - last < d);
181 last = gettimeticks();
182 }
183 mstate=0;
184
185 }
186
handle_evbll(void)187 void handle_evbll(void){
188 static long last=0;
189 static int rest_cnt=0;
190 int i;
191
192 #ifndef ALLEGRO_DOS
193 yield_timeslice();
194 #endif
195 i = (15*app_data.speed/100);
196 rest_cnt = (rest_cnt+1)%(i<5?5:i);
197 #ifdef ALLEGRO_WINDOWS
198 if (rest_cnt==0) rest(1);
199 #endif
200
201 /******************* 150 */
202
203 for (i=150; i<MAXLINES; i++) {
204 ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
205 AudioVector[i] = VDCwrite[0xAA];
206 }
207
208 if (key2vcnt++ > 10) {
209 key2vcnt=0;
210 for (i=0; i<128; i++) key2[i] = 0;
211 dbstick1 = dbstick2 = 0;
212 }
213 if (app_data.limit) {
214 long d,f;
215 d = (TICKSPERSEC*100)/(app_data.speed*fps);
216 f = ((d-gettimeticks()+last)*1000)/TICKSPERSEC;
217 if (f>0) {
218 #ifdef ALLEGRO_WINDOWS
219 f = f-(f%10);
220 if (f>5) rest(f-5);
221 #else
222 #ifndef ALLEGRO_DOS
223 yield_timeslice();
224 #endif
225 #endif
226 }
227 while (gettimeticks() - last < d);
228 last = gettimeticks();
229 }
230 mstate=0;
231 }
232
init_system(void)233 void init_system(void){
234 int i,j,k;
235
236 last_line=0;
237 dbstick1=0x00;
238 dbstick2=0x00;
239 mstate=0;
240 master_clk=0;
241 h_clk=0;
242 line_count=0;
243 itimer=0;
244 clk_counter=0;
245 init_roms();
246 for(i=0; i<256; i++) {
247 VDCwrite[i]=0;
248 extRAM[i]=0;
249 }
250 for(i=0; i<64; i++) {
251 intRAM[i]=0;
252 }
253 for (i=0; i<MAXLINES; i++) AudioVector[i] = ColorVector[i] = 0;
254
255 for (i=0; i<MAXLINES+2*MAXSNAP; i++)
256 for (j=0; j<256; j++)
257 for (k=0; k<2; k++)
258 snapedlines[i][j][k]=0;
259
260 if (app_data.stick[0] == 2 || app_data.stick[1] == 2) {
261 i = install_joystick(JOY_TYPE_AUTODETECT);
262 if (i || (num_joysticks<1)) {
263 fprintf(stderr,"Error: no joystick detected\n");
264 exit(EXIT_FAILURE);
265 }
266 }
267 for (i=0; i<128; i++) key2[i] = 0;
268 key2vcnt=0;
269 if (app_data.euro)
270 setvideomode(1);
271 else
272 setvideomode(0);
273 do_kluges();
274 init_vpp();
275 clear_collision();
276 }
277
278
init_roms(void)279 void init_roms(void){
280 rom=rom_table[0];
281 romlatch=0;
282 }
283
284
read_t1(void)285 Byte read_t1(void){
286 if ((h_clk > 17) || (master_clk > VBLCLK))
287 return 1;
288 else
289 return 0;
290 }
291
292
write_p1(Byte d)293 void write_p1(Byte d){
294 if ((d & 0x80) != (p1 & 0x80)) {
295 int i,l;
296 l = snapline((int)((float)master_clk/22.0+0.1), VDCwrite[0xA3], 1);
297 for (i=l; i<MAXLINES; i++) ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (d & 0x80);
298 }
299 p1 = d;
300 if (app_data.bank == 2) {
301 rom=rom_table[~p1 & 0x01];
302 } else if (app_data.bank == 3) {
303 rom=rom_table[~p1 & 0x03];
304 } else if (app_data.bank == 4) {
305 rom=rom_table[(p1 & 1)?0:romlatch];
306 }
307 }
308
309
read_P2(void)310 Byte read_P2(void){
311 int i,si,so,km;
312
313 if (NeedsPoll) poll_keyboard();
314
315 if (!(p1 & 0x04)) {
316 si = (p2 & 7);
317 so=0xff;
318 if (si<6) {
319 for (i=0; i<8; i++) {
320 km = key_map[si][i];
321 if ((key[km] && ((!joykeystab[km]) || (key_shifts & KB_CAPSLOCK_FLAG))) || (key2[km])) {
322 so = i ^ 0x07;
323 }
324 }
325 }
326 if (so != 0xff) {
327 p2 = p2 & 0x0F;
328 p2 = p2 | (so << 5);
329 } else {
330 p2 = p2 | 0xF0;
331 }
332 } else {
333 p2 = p2 | 0xF0;
334 }
335 return(p2);
336
337 }
338
339
ext_read(ADDRESS adr)340 Byte ext_read(ADDRESS adr){
341 Byte d;
342 Byte si;
343 Byte m;
344 int i;
345
346 if (!(p1 & 0x08) && !(p1 & 0x40)) {
347 /* Handle VDC Read */
348 switch(adr) {
349 case 0xA1:
350 d = VDCwrite[0xA0] & 0x02;
351 if (master_clk > VBLCLK) d = d | 0x08;
352 if (h_clk < (LINECNT-7)) d = d | 0x01;
353 if (sound_IRQ) d = d | 0x04;
354 sound_IRQ=0;
355 return d;
356 case 0xA2:
357 si = VDCwrite[0xA2];
358 m=0x01;
359 d=0;
360 for(i=0; i<8; i++) {
361 if (si & m) {
362 if (coltab[1] & m) d = d | (coltab[1] & (m ^ 0xFF));
363 if (coltab[2] & m) d = d | (coltab[2] & (m ^ 0xFF));
364 if (coltab[4] & m) d = d | (coltab[4] & (m ^ 0xFF));
365 if (coltab[8] & m) d = d | (coltab[8] & (m ^ 0xFF));
366 if (coltab[0x10] & m) d = d | (coltab[0x10] & (m ^ 0xFF));
367 if (coltab[0x20] & m) d = d | (coltab[0x20] & (m ^ 0xFF));
368 if (coltab[0x80] & m) d = d | (coltab[0x80] & (m ^ 0xFF));
369 }
370 m = m << 1;
371 }
372 clear_collision();
373 return d;
374 case 0xA5:
375 if (!(VDCwrite[0xA0] & 0x02)) {
376 return x_latch;
377 }
378 else {
379 x_latch = h_clk * 12;
380 return x_latch;
381 }
382 case 0xA4:
383 if (!(VDCwrite[0xA0] & 0x02)) {
384 return y_latch;
385 }
386 else {
387 y_latch = master_clk/22;
388 if (y_latch > 241) y_latch=0xFF;
389 return y_latch;
390 }
391 default:
392 return VDCwrite[adr];
393 }
394 } else if (!(p1 & 0x10)) {
395 /* Handle ext RAM Read */
396 return extRAM[adr & 0xFF];
397 } else if (!(p1 & 0x20)) {
398 /* Read a Videopac+ register */
399 return vpp_read(adr);
400 } else if (app_data.exrom && (p1 & 0x02)) {
401 /* Handle read from exrom */
402 return extROM[(p2 << 8) | (adr & 0xFF)];
403 }
404
405 return 0;
406 }
407
408
in_bus(void)409 Byte in_bus(void){
410 Byte si=0,d=0,mode=0,jn=0;
411
412 if ((p1 & 0x08) && (p1 & 0x10)) {
413 /* Handle joystick read */
414 if (!(p1 & 0x04)) {
415 si = (p2 & 7);
416 }
417 d=0xFF;
418 if (si == 1) {
419 mode = app_data.stick[0];
420 jn = 0;
421 } else {
422 mode = app_data.stick[1];
423 jn = 1;
424 }
425 switch(mode) {
426 case 1:
427 d = keyjoy(jn);
428 break;
429 case 2:
430 poll_joystick();
431 if (joy_up) d &= 0xFE;
432 if (joy_right) d &= 0xFD;
433 if (joy_down) d &= 0xFB;
434 if (joy_left) d &= 0xF7;
435 if (joy_b1) d &= 0xEF;
436 break;
437 }
438 if (si == 1) {
439 if (dbstick1) d = dbstick1;
440 } else {
441 if (dbstick2) d = dbstick2;
442 }
443 }
444 return d;
445 }
446
447
ext_write(Byte dat,ADDRESS adr)448 void ext_write(Byte dat, ADDRESS adr){
449 int i;
450
451 if (!(p1 & 0x08)) {
452 /* Handle VDC Write */
453 if (adr == 0xA0){
454 if ((VDCwrite[0xA0] & 0x02) && !(dat & 0x02)) {
455 y_latch = master_clk/22;
456 x_latch = h_clk * 12;
457 if (y_latch > 241) y_latch=0xFF;
458 }
459 if ((master_clk <= VBLCLK) && (VDCwrite[0xA0] != dat)) {
460 draw_region();
461 }
462 } else if (adr == 0xA3){
463 int l;
464 l = snapline((int)((float)master_clk/22.0+0.5), dat, 1);
465 for (i=l; i<MAXLINES; i++) ColorVector[i] = (dat & 0x7f) | (p1 & 0x80);
466 } else if (adr == 0xAA) {
467 for (i=master_clk/22; i<MAXLINES; i++) AudioVector[i]=dat;
468 }
469 VDCwrite[adr]=dat;
470 } else if (!(p1 & 0x10) && !(p1 & 0x40)) {
471 adr = adr & 0xFF;
472 if (adr < 0x80) {
473 /* Handle ext RAM Write */
474 extRAM[adr] = dat;
475 } else {
476
477 if (app_data.bank == 4) {
478 romlatch = (~dat) & 7;
479 rom=rom_table[(p1 & 1)?0:romlatch];
480 }
481
482 /* Handle The Voice */
483 if (!(dat & 0x20))
484 reset_voice();
485 else {
486 if (adr == 0xE4)
487 set_voice_bank(0);
488 else if ((adr >= 0xE8) && (adr <= 0xEF))
489 set_voice_bank(adr-0xE7);
490 else if (((adr >= 0x80) && (adr <= 0xDF)) || ((adr >= 0xF0) && (adr <= 0xFF)))
491 trigger_voice(adr);
492 }
493 }
494 } else if (!(p1 & 0x20)) {
495 /* Write to a Videopac+ register */
496 vpp_write(dat,adr);
497 }
498 }
499
500
do_kluges(void)501 static void do_kluges(void){
502 if (app_data.crc == 0xA7344D1F) pendirq=1; /* Atlantis */
503
504 if (app_data.crc == 0xFB83171E) pendirq=1; /* Blockout */
505 if (app_data.crc == 0xD38153F6) pendirq=1; /* Blockout (french) */
506 if (app_data.crc == 0x881CEAE4) pendirq=1; /* Wall Street */
507
508 if (app_data.crc == 0x9E42E766) useforen=1; /* Turtles */
509 if (app_data.crc == 0x1C750349) useforen=1; /* Turtles (European version) */
510 if (app_data.crc == 0x202F2749) useforen=1; /* Q*bert */
511 if (app_data.crc == 0x06861A9C) useforen=1; /* Flashpoint 5 (Videopac adaption) */
512
513 if (app_data.crc == 0xFB83171E) enahirq=0; /* Blockout*/
514 if (app_data.crc == 0xD38153F6) enahirq=0; /* Blockout (french) */
515
516 if (app_data.crc == 0xFB83171E) regionoff=1; /* Blockout*/
517 if (app_data.crc == 0xD38153F6) regionoff=1; /* Blockout (french) */
518 if (app_data.crc == 0x202F2749) regionoff=0; /* Q*bert */
519 if (app_data.crc == 0x5216771A) regionoff=1; /* Popeye */
520 if (app_data.crc == 0x0C2E4811) regionoff=11; /* Out of this World! / Helicopter Rescue! */
521 if (app_data.crc == 0x67069924) regionoff=11; /* Smithereens! */
522 if (app_data.crc == 0x44D1A8A5) regionoff=11; /* Smithereens! (European version) */
523 if (app_data.crc == 0x2391C2FB) regionoff=11; /* Smithereens! + */
524 if (app_data.crc == 0xBB4AD548) regionoff=11; /* Smithereens! modified 1 */
525 if (app_data.crc == 0x25057C11) regionoff=11; /* Smithereens! modified 2 */
526 if (app_data.crc == 0xB936BD78) regionoff=12; /* Type & Tell */
527 if (app_data.crc == 0xAD8B9AE0) regionoff=2; /* Type & Tell modified 1 */
528 if (app_data.crc == 0x5C02BEE6) regionoff=2; /* Type & Tell modified 2 */
529 if (app_data.crc == 0xDC30AD3D) regionoff=10; /* Dynasty! */
530 if (app_data.crc == 0x7810BAD5) regionoff=8; /* Dynasty! (European) */
531 if (app_data.crc == 0xA7344D1F) regionoff=0; /* Atlantis */
532
533 if (app_data.crc == 0xD0BC4EE6) regionoff=12; /* Frogger */
534
535 if (app_data.crc == 0xA57D84F3) regionoff=8; /* Frogger BR */
536 if (app_data.crc == 0x825976A9) regionoff=0; /* Mousing Cat 8kb */
537 if (app_data.crc == 0xF390BFEC) regionoff=0; /* Mousing Cat 4kb */
538 if (app_data.crc == 0x61A350E6) regionoff=0; /* Mousing Cat (french) */
539 if (app_data.crc == 0x3BFEF56B) regionoff=1; /* Four in 1 Row! */
540 if (app_data.crc == 0x7C747245) regionoff=1; /* Four in 1 Row! modified */
541 if (app_data.crc == 0x9B5E9356) regionoff=1; /* Four in 1 Row! (french) */
542
543 if (app_data.crc == 0x6CEBAB74) regionoff=12; /* P.T. Barnum's Acrobats! (European version) */
544 if (app_data.crc == 0xE7B26A56) regionoff=12; /* P.T. Barnum's Acrobats! (European version - Extra keys) */
545
546 if (app_data.crc == 0xFB83171E) mxsnap=3; /* Blockout*/
547 if (app_data.crc == 0xD38153F6) mxsnap=3; /* Blockout (french) */
548 if (app_data.crc == 0xA57E1724) mxsnap=12; /* Catch the Ball / Noughts and Crosses */
549 if (app_data.crc == 0xBE4FF48E) mxsnap=12; /* Catch the Ball / Noughts and Crosses modified */
550 if (app_data.crc == 0xFD179F6D) mxsnap=3; /* Clay Pigeon! */
551 if (app_data.crc == 0x9C9DDDF9) mxsnap=3; /* Verkehr */
552 if (app_data.crc == 0x95936B07) mxsnap=3; /* Super Cobra */
553 if (app_data.crc == 0x881CEAE4) mxsnap=3; /* Wall Street */
554 if (app_data.crc == 0x9E42E766) mxsnap=0; /* Turtles */
555 if (app_data.crc == 0x1C750349) mxsnap=0; /* Turtles (European version) */
556
557 if (app_data.crc == 0xD0BC4EE6) mxsnap=3; /* Frogger */
558
559 if (app_data.crc == 0xA57D84F3) mxsnap=3; /* Frogger BR */
560 if (app_data.crc == 0x3BFEF56B) mxsnap=6; /* Four in 1 Row! */
561 if (app_data.crc == 0x9B5E9356) mxsnap=6; /* Four in 1 Row! (french) */
562 if (app_data.crc == 0x7C747245) mxsnap=6; /* Four in 1 Row! modified */
563
564 if (app_data.crc == 0xA7344D1F) setvideomode(1); /* Atlantis */
565 if (app_data.crc == 0x39E31BF0) setvideomode(1); /* Jake */
566 if (app_data.crc == 0x92D0177B) setvideomode(1); /* Jake (hack) */
567 if (app_data.crc == 0x3351FEDA) setvideomode(1); /* Power Lords */
568 if (app_data.crc == 0x40AE062D) setvideomode(1); /* Power Lords (alternate) */
569 if (app_data.crc == 0xD158EEBA) setvideomode(1); /* Labirinth */
570 if (app_data.crc == 0x26B0FF5B) setvideomode(1); /* Nightmare */
571 if (app_data.crc == 0xDF36683F) setvideomode(1); /* Shark Hunter */
572 if (app_data.crc == 0xAF307559) setvideomode(1); /* Super Bee 8Kb */
573 if (app_data.crc == 0x9585D511) setvideomode(1); /* Super Bee 4Kb */
574 if (app_data.crc == 0x58FA6766) setvideomode(1); /* War of the Nerves */
575 if (app_data.crc == 0x58FA6766) setvideomode(1); /* War of the Nerves */
576 if (app_data.crc == 0x39989464) setvideomode(1); /* Hockey! / Soccer! */
577 if (app_data.crc == 0x3BFEF56B) setvideomode(1); /* Four in 1 Row! */
578 if (app_data.crc == 0x9B5E9356) setvideomode(1); /* Four in 1 Row! (french) */
579 if (app_data.crc == 0x7C747245) setvideomode(1); /* Four in 1 Row! modified */
580 if (app_data.crc == 0x68560DC7) setvideomode(1); /* Jopac Moto Crash */
581 if (app_data.crc == 0x020FCA15) setvideomode(1); /* Jopac Moto Crash modified (non VP+) */
582 if (app_data.crc == 0xC4134DF8) setvideomode(1); /* Helicopter Rescue + */
583 if (app_data.crc == 0x0D2D721D) setvideomode(1); /* Trans American Rally + */
584 if (app_data.crc == 0x9D72D4E9) setvideomode(1); /* Blobbers */
585 if (app_data.crc == 0xB2F0F0B4) setvideomode(1); /* Le Tresor Englouti + */
586 if (app_data.crc == 0x0B2DEB61) setvideomode(1); /* Tutankham */
587 if (app_data.crc == 0x313547EB) setvideomode(1); /* VP53 */
588 if (app_data.crc == 0x06861A9C) setvideomode(1); /* Flashpoint 5 (Videopac adaption) */
589 if (app_data.crc == 0xA57E1724) setvideomode(0); /* Catch the Ball / Noughts and Crosses */
590 if (app_data.crc == 0xBE4FF48E) setvideomode(0); /* Catch the Ball / Noughts and Crosses modified */
591 if (app_data.crc == 0xFB83171E) setvideomode(0); /* Blockout*/
592 if (app_data.crc == 0xD38153F6) setvideomode(0); /* Blockout (french) */
593 if (app_data.crc == 0x9BFC3E01) setvideomode(0); /* Demon Attack */
594 if (app_data.crc == 0x50AF9D45) setvideomode(0); /* Demon Attack + */
595 if (app_data.crc == 0x9884EF36) setvideomode(0); /* Demon Attack + modified */
596 if (app_data.crc == 0x4A578DFE) setvideomode(0); /* Restaurant ntsc */
597 if (app_data.crc == 0x863D5E2D) setvideomode(0); /* Shark Hunter ntsc */
598
599 if (app_data.crc == 0xD62814A3) evblclk=12000; /* Pick Axe Pete */
600 if (app_data.crc == 0xB2FFB353) evblclk=12000; /* Pick Axe Pete + */
601 if (app_data.crc == 0x81C20196) evblclk=12000; /* Pick Axe Pete + (modified) */
602
603 if ((app_data.crc == 0xF390BFEC) || (app_data.crc == 0x825976A9) || (app_data.crc == 0x61A350E6)){ /* Mousing Cat */
604 setvideomode(1);
605 evblclk=7642;
606 }
607
608 if (app_data.crc == 0xD0BC4EE6) { /* Frogger */
609 setvideomode(1);
610 evblclk=7642;
611
612 }
613 if (app_data.crc == 0x26517E77) { /* Commando Noturno */
614 setvideomode(1);
615 evblclk=6100;
616 regionoff=12;
617 }
618 if (app_data.crc == 0xA57E1724) { /* Catch the ball*/
619 regionoff=5;
620 sproff=1;
621
622 }
623
624 if ((app_data.crc == 0x2DCB77F0) || (app_data.crc == 0xF6882734)) { /* Depth Charge / Marksman */
625 setvideomode(1);
626 evblclk=8000;
627 }
628 if (app_data.crc == 0x881CEAE4) { /* Wall Street */
629 setvideomode(1);
630 evblclk=6100;
631 }
632 if (app_data.crc == 0xD0BC4EE6) tweakedaudio=1; /* Frogger */
633 if (app_data.crc == 0xA57D84F3) tweakedaudio=1; /* Frogger BR */
634 if (app_data.crc == 0x5216771A) tweakedaudio=1; /* Popeye */
635 if (app_data.crc == 0xAFB23F89) tweakedaudio=1; /* Musician */
636 if (app_data.crc == 0xC4134DF8) tweakedaudio=1; /* Helicopter Rescue + */
637 if (app_data.crc == 0x0D2D721D) tweakedaudio=1; /* Trans American Rally + */
638
639 if (app_data.crc == 0xD3B09FEC) sproff=1; /* Volleyball! */
640 if (app_data.crc == 0x551E38A2) sproff=1; /* Volleyball! (french) */
641
642 }
643
644
snapline(int pos,Byte reg,int t)645 int snapline(int pos, Byte reg, int t){
646 int i;
647 if (pos<MAXLINES+MAXSNAP+MAXSNAP) {
648 for (i=0; i<mxsnap; i++){
649 if (snapedlines[pos+MAXSNAP-i][reg][t]) return pos-i;
650 if (snapedlines[pos+MAXSNAP+i][reg][t]) return pos+i;
651 }
652 snapedlines[pos+MAXSNAP][reg][t]=1;
653 }
654 return pos;
655 }
656
657
setvideomode(int t)658 static void setvideomode(int t){
659 if (t) {
660 evblclk = EVBLCLK_PAL;
661 fps = FPS_PAL;
662 } else {
663 evblclk = EVBLCLK_NTSC;
664 fps = FPS_NTSC;
665 }
666 }
667