1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU Library General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */
16 
17 /**************************************************************************/
18 /*                 'Portable' PC-Engine Emulator Source file              */
19 /*                                                                        */
20 /*      1998 by BERO bero@geocities.co.jp                                 */
21 /*                                                                        */
22 /*    Modified 1998 by hmmx hmmx@geocities.co.jp                          */
23 /*    Modified 1999-2005 by Zeograd (Olivier Jolly) zeograd@zeograd.com   */
24 /**************************************************************************/
25 
26 /* Header section */
27 
28 #include "pce.h"
29 #include "iso_ent.h"
30 #include "miniunz.h"
31 #include "utils.h"
32 #if defined(BSD_CD_HARDWARE_SUPPORT)
33 #include "pcecd.h"
34 #endif
35 
36 #define LOG_NAME "hugo.log"
37 
38 #define CD_FRAMES 75
39 #define CD_SECS 60
40 
41 /* Variable section */
42 
43 UChar minimum_bios_hooking = 0;
44 
45 UChar can_write_debug = 0;
46 
47 UChar *cd_buf = NULL;
48 
49 UChar *PopRAM;
50 // Now dynamicaly allocated
51 // ( size of popRAMsize bytes )
52 // If someone could explain me why we need it
53 // the version I have works well without this trick
54 
55 const UInt32 PopRAMsize = 0x8000;
56 // I don't really know if it must be 0x8000 or 0x10000
57 
58 #define ZW      64
59 //byte ZBuf[ZW*256];
60 //BOOL IsROM[8];
61 
62 UChar *ROM;
63 // IOAREA = a pointer to the emulated IO zone
64 // vchange = array of boolean to know whether bg tiles have changed (i.e.
65 //    vchanges[5]==1 means the 6th tile have changed and VRAM2 should be updated)
66 //    [to check !]
67 // vchanges IDEM for sprites
68 // ROM = the same thing as the ROM file (w/o header)
69 
70 UChar CDBIOS_replace[0x4d][2];
71 // Used to know what byte do we have replaced to hook bios functions so that
72 // we can restore them if needed
73 
74 int ROM_size;
75 // obvious, no ?
76 // actually, the number of block of 0x2000 bytes in the rom
77 
78 extern SInt32 vmode;
79 // What is the favorite video mode to use
80 
81 SInt32 smode;
82 // what sound card type should we use? (0 means the silent one,
83 // my favorite : the fastest!!! ; and -1 means AUTODETECT;
84 // later will avoid autodetection if wanted)
85 
86 SChar silent = 1;
87 // a bit different from the previous one, even if asked to
88 // use a card, we could not be able to make sound...
89 
90 /*
91  * nb_joy no more used
92  * unsigned char nb_joy = 1;
93  * number of input to poll
94  */
95 
96 int Country;
97 /* Is this^ initialised anywhere ?
98  * You may try to play with if some games don't want to start
99  * it could be useful on some cases
100  */
101 
102 int IPeriod;
103 // Number of cycle between two interruption calls
104 
105 UInt32 TimerCount;
106 // int CycleOld;
107 // int TimerPeriod;
108 int scanlines_per_frame = 263;
109 
110 //int MinLine = 0,MaxLine = 255;
111 //#define MAXDISP 227
112 
113 char cart_name[PATH_MAX] = "";
114 // Name of the file containing the ROM
115 
116 char short_cart_name[PATH_MAX];
117 // Just the filename without the extension (with a dot)
118 // you just have to add your own extension...
119 
120 char short_iso_name[PATH_MAX];
121 // Just the ISO filename without the extension (with a dot)
122 // you just have to add your own extension...
123 
124 UChar hook_start_cd_system = 0;
125 // Do we hook CD system to avoid pressing start on main screen
126 
127 UChar use_eagle = 0;
128 // eagle use ?
129 
130 UChar use_scanline = 0;
131 // use scanline mode ?
132 
133 char true_file_name[PATH_MAX];
134 // the name of the file containing the ROM (with path, ext)
135 // Now needed 'coz of ZIP archiving...
136 
137 char short_exe_name[PATH_MAX];
138 // Used to function whatever the launching directory
139 // Help working under WIN9X without troubles
140 // Actually, the path of the EXE
141 
142 char sav_path[PATH_MAX];
143 // The filename for saving games
144 
145 char sav_basepath[PATH_MAX];
146 // base path for saved games
147 
148 char tmp_basepath[PATH_MAX];
149 // base path for temporary operations
150 
151 char video_path[PATH_MAX];
152 // The place where to keep output pictures
153 
154 char ISO_filename[PATH_MAX] = "";
155 // The name of the ISO file
156 
157 UChar force_header = 1;
158 // Force the first sector of the code track to be the correct header
159 
160 char* server_hostname = NULL;
161 
162 /*
163 ####################################
164 ####################################
165 ####################################
166 ####################################
167 2KILL :: BEGIN
168 ####################################
169 ####################################
170 ####################################
171 ####################################
172 */
173 #if defined(EXTERNAL_DAT) && defined(ALLEGRO)
174 DATAFILE *datafile;
175 // A pointer to the datafile where we keep bitmaps...
176 // Make things looks cleaner.
177 #endif
178 /*
179 ####################################
180 ####################################
181 ####################################
182 ####################################
183 2KILL :: END
184 ####################################
185 ####################################
186 ####################################
187 ####################################
188 */
189 
190 char *bmdefault = NULL;
191 // Name of the backup memory
192 
193 UChar cart_reload = 0;
194 // Once the game ended, do we need to load another rom
195 // i.e. do we escape game by pressing F12 or do we called the file selector
196 
197 char effectively_played = 0;
198 // Well, the name is enough I think...
199 
200 UChar populus = 0;
201 // no more hasardous detection
202 // thanks to the CRC detection
203 // now, used to know whether the save file
204 // must contain extra info
205 
206 UChar US_encoded_card = 0;
207 // Do we have to swap bit order in the rom
208 
209 UInt16 NO_ROM;
210 // Number of the ROM in the database or 0xFFFF if unknown
211 
212 UChar debug_on_beginning = 0;
213 // Do we have to set a bp on the reset IP
214 
215 UChar CD_emulation = 0;
216 // Do we emulate CD ( == 1)
217 //            or  ISO file   ( == 2)
218 //            or  ISQ file   ( == 3)
219 //            or  plain BIN file ( == 4)
220 //            or  HCD ( == 5)
221 
222 UChar builtin_system_used = 0;
223 // Have we used the .dat included rom or no ?
224 
225 int scroll = 0;
226 
227 signed char snd_vol[6][32];
228 // cooked volume for each channel
229 
230 Track CD_track[0x100];
231 // Track
232 // beg_min -> beginning in minutes since the begin of the CD(BCD)
233 // beg_sec -> beginning in seconds since the begin of the CD(BCD)
234 // beg_fr -> beginning in frames   since the begin of the CD(BCD)
235 // type -> 0 = audio, 4 = data
236 // beg_lsn -> beginning in number of sector (2048 bytes)
237 // length -> number of sector
238 
239 /*
240 ####################################
241 ####################################
242 ####################################
243 ####################################
244 2KILL :: END
245 ####################################
246 ####################################
247 ####################################
248 ####################################
249 */
250 
251 volatile SChar key_delay = 0;
252 // delay to avoid too many key strokes
253 
254 static volatile unsigned char can_blit = 1;
255 // used to sync screen to 60 image/sec.
256 
257 volatile UInt32 message_delay = 0;
258 // if different of zero, we must display the message pointed by pmessage
259 
260 char exit_message[256] = "";
261 // What we must display at the end
262 
263 UChar language;
264 /* The language of the messages
265  * 0 -> English
266  * 1 -> French
267  * 2 -> Spanish
268  * 3 -> Slovenian
269  * 4 -> Portuguese
270  * 5 -> German
271  * 6 -> Dutch
272  * 7 -> Polish
273  * 8 -> Italian
274  */
275 
276 unsigned char binbcd[0x100] = {
277   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
278   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
279   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
280   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
281   0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
282   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
283   0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
284   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
285   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
286   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
287 };
288 
289 
290 unsigned char bcdbin[0x100] = {
291   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0, 0, 0, 0, 0, 0,
292   0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0, 0, 0, 0, 0, 0,
293   0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0, 0, 0, 0, 0, 0,
294   0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0, 0, 0, 0, 0, 0,
295   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0, 0, 0, 0, 0, 0,
296   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0, 0, 0, 0, 0, 0,
297   0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0, 0, 0, 0, 0, 0,
298   0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0, 0, 0, 0, 0, 0,
299   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0, 0, 0, 0, 0, 0,
300   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0, 0, 0, 0, 0, 0,
301 };
302 
303 UChar pce_cd_adpcm_trans_done = 0;
304 
305 FILE *iso_FILE = NULL;
306 
307 const char* joymap_reverse[J_MAX] = {
308 	"UP", "DOWN", "LEFT", "RIGHT",
309 	"I", "II", "SELECT", "RUN",
310 	"AUTOI", "AUTOII", "PI", "PII",
311 	"PSELECT", "PRUN", "PAUTOI", "PAUTOII",
312 	"PXAXIS", "PYAXIS"};
313 
314 
315 /*
316 ####################################
317 ####################################
318 ####################################
319 ####################################
320 2KILL :: BEGIN
321 ####################################
322 ####################################
323 ####################################
324 ####################################
325 */
326 #ifdef ALLEGRO
327 PACKFILE *packed_iso_FILE = NULL;
328 #endif
329 /*
330 ####################################
331 ####################################
332 ####################################
333 ####################################
334 2KILL :: END
335 ####################################
336 ####################################
337 ####################################
338 ####################################
339 */
340 
341 UInt32 packed_iso_filesize = 0;
342 
343 UInt32 ISQ_position = 0;
344 
345 // struct cdrom_tocentry pce_cd_tocentry;
346 
347 UChar nb_max_track = 24;	//(NO MORE BCD!!!!!)
348 
349 //char cdsystem_path[256];
350 
351 //extern char   *pCartName;
352 
353 //extern char snd_bSound;
354 
355 UInt32 timer_60 = 0;
356 // how many times do the interrupt have been called
357 
358 int UPeriod = 0;
359 // Number of frame to skip
360 
361 int BaseClock;
362 
363 UChar video_driver = 0;
364 /* 0 => Normal driver, normal display
365  * 1 => Eagle graphism
366  * 2 => Scanline graphism
367  */
368 
369 #if defined(SHARED_MEMORY)
370 //! Handle for shared memory holding the rom content
371 static int shm_rom_handle;
372 #endif
373 
374 // Pre declaration of reading function routines
375 void read_sector_dummy (unsigned char *, UInt32);
376 void read_sector_CD (unsigned char *, UInt32);
377 void read_sector_ISO (unsigned char *, UInt32);
378 void read_sector_ISQ (unsigned char *, UInt32);
379 void read_sector_BIN (unsigned char *, UInt32);
380 void read_sector_HCD (unsigned char *, UInt32);
381 
382 void (*read_sector_method[6]) (unsigned char *, UInt32) =
383 {
384 read_sector_dummy,
385     read_sector_CD,
386     read_sector_ISO, read_sector_ISQ, read_sector_BIN, read_sector_HCD};
387 
388 static char *
check_char(char * s,char c)389 check_char (char *s, char c)
390 {
391   while ((*s) && (*s != c))
392     s++;
393   return *s == c ? s : NULL;
394 }
395 
396 
397 #if defined(ALLEGRO)
interrupt_60hz(void)398 void interrupt_60hz (void)
399 #elif defined(SDL)
400 UInt32 interrupt_60hz (UInt32 interval, void *param)
401 #endif
402 {
403 
404   /* Refresh freezed values in RAM */
405   for (can_blit = 0; can_blit < current_freezed_values; can_blit++)
406     RAM[list_to_freeze[can_blit].position] = list_to_freeze[can_blit].value;
407 
408   /* Make the system understand it can blit */
409   can_blit = 1;
410 
411   /* If we've displayed a message recently, make it less recent */
412   if (message_delay)
413     message_delay--;
414 
415   /* number of call of this function */
416   timer_60++;
417 
418 #if defined(ALLEGRO)
419 
420   /* If we've pressed a key recently, make it less recent =) */
421   if (key_delay)
422     key_delay--;
423 
424   return;
425 #elif defined(SDL)
426   return interval;
427 #endif
428 };
429 
430 /*
431 ####################################
432 ####################################
433 ####################################
434 ####################################
435 2KILL :: BEGIN
436 ####################################
437 ####################################
438 ####################################
439 ####################################
440 */
441 #ifdef ALLEGRO
442 
443 /*
444  * For allegro, when calling regulary a function trought the timer, we must
445  * tell when does the function stops
446  */
447 
448 END_OF_FUNCTION (interrupt_60hz);
449 
450 #endif
451 /*
452 ####################################
453 ####################################
454 ####################################
455 ####################################
456 2KILL :: END
457 ####################################
458 ####################################
459 ####################################
460 ####################################
461 */
462 
463 #if defined(ALLEGRO)
464 
465 void
delete_file_tmp(char * name,int dummy,int dummy2)466 delete_file_tmp (char *name, int dummy, int dummy2)
467 {
468   delete_file (name);
469 };
470 
471 #endif
472 
473 /*****************************************************************************
474 
475     Function: init_log_file
476 
477     Description: destroy the current log file, and create another
478     Parameters: none
479     Return: nothin
480 
481 *****************************************************************************/
482 void
init_log_file()483 init_log_file ()
484 {
485 #ifdef MSDOS
486 
487   struct time Time;
488   struct date Date;
489 
490 #endif
491 
492   unlink (log_filename);
493   Log ("--[ INITIALISATION ]--------------------------------\n");
494 
495 #ifdef MSDOS
496 
497   getdate (&Date);
498   gettime (&Time);
499   Log
500     ("Creating Dos Hu-Go! log file on %02d:%02d:%02d.%02d, the %d/%d/%d\nVersion 2.12 of %s\n",
501      Time.ti_hour, Time.ti_min, Time.ti_sec, Time.ti_hund, Date.da_day,
502      Date.da_mon, Date.da_year, __DATE__);
503 
504 #elif defined(LINUX)
505   Log ("Creating Linux log file version 2.12 of %s ($Revision: 1.66 $)\n", __DATE__);
506 #elif defined(WIN32)
507   Log ("Creating Win32 log file version 2.12 of %s ($Revision: 1.66 $)\n", __DATE__);
508 #endif
509 
510 }
511 
512 extern int op6502_nb;
513 
514 void
fill_cd_info()515 fill_cd_info ()
516 {
517 
518   UChar Min, Sec, Fra;
519   UChar current_track;
520 
521   // Track 1 is almost always a audio avertising track
522   // 30 sec. seems usual
523 
524   CD_track[1].beg_min = binbcd[00];
525   CD_track[1].beg_sec = binbcd[02];
526   CD_track[1].beg_fra = binbcd[00];
527 
528   CD_track[1].type = 0;
529   CD_track[1].beg_lsn = 0;	// Number of sector since the
530   // beginning of track 1
531 
532   CD_track[1].length = 47 * CD_FRAMES + 65;	// Most common
533 
534   nb_sect2msf (CD_track[1].length, &Min, &Sec, &Fra);
535 
536   // Second track is the main code track
537 
538   CD_track[2].beg_min = binbcd[bcdbin[CD_track[1].beg_min] + Min];
539   CD_track[2].beg_sec = binbcd[bcdbin[CD_track[1].beg_sec] + Sec];
540   CD_track[2].beg_fra = binbcd[bcdbin[CD_track[1].beg_fra] + Fra];
541 
542   CD_track[2].type = 4;
543   CD_track[2].beg_lsn =
544     msf2nb_sect (bcdbin[CD_track[2].beg_min] - bcdbin[CD_track[1].beg_min],
545 		 bcdbin[CD_track[2].beg_sec] - bcdbin[CD_track[1].beg_sec],
546 		 bcdbin[CD_track[2].beg_fra] - bcdbin[CD_track[1].beg_fra]);
547   switch (CD_emulation)
548     {
549     case 2:
550       CD_track[0x02].length = filesize (iso_FILE) / 2048;
551       break;
552     case 3:
553       CD_track[0x02].length = packed_iso_filesize / 2048;
554       break;
555     case 4:
556       CD_track[0x02].length = 140000;
557       break;
558     default:
559       break;
560     }
561 
562 
563 
564 
565   // Now most track are audio
566 
567   for (current_track = 3; current_track < bcdbin[nb_max_track];
568        current_track++)
569     {
570 
571       Fra = CD_track[current_track - 1].length % CD_FRAMES;
572       Sec = (CD_track[current_track - 1].length / CD_FRAMES) % CD_SECS;
573       Min = (CD_track[current_track - 1].length / CD_FRAMES) / CD_SECS;
574 
575       CD_track[current_track].beg_min =
576 	binbcd[bcdbin[CD_track[current_track - 1].beg_min] + Min];
577       CD_track[current_track].beg_sec =
578 	binbcd[bcdbin[CD_track[current_track - 1].beg_sec] + Sec];
579       CD_track[current_track].beg_fra =
580 	binbcd[bcdbin[CD_track[current_track - 1].beg_fra] + Fra];
581 
582       CD_track[current_track].type = 0;
583       CD_track[current_track].beg_lsn =
584 	msf2nb_sect (bcdbin[CD_track[current_track].beg_min] -
585 		     bcdbin[CD_track[1].beg_min],
586 		     bcdbin[CD_track[current_track].beg_sec] -
587 		     bcdbin[CD_track[1].beg_sec],
588 		     bcdbin[CD_track[current_track].beg_fra] -
589 		     bcdbin[CD_track[1].beg_fra]);
590       // 1 min for all
591       CD_track[current_track].length = 1 * CD_SECS * CD_FRAMES;
592 
593     }
594 
595   // And the last one is generally also code
596 
597 
598   Fra = CD_track[nb_max_track - 1].length % CD_FRAMES;
599   Sec = (CD_track[nb_max_track - 1].length / CD_FRAMES) % CD_SECS;
600   Min = (CD_track[nb_max_track - 1].length / CD_FRAMES) / CD_SECS;
601 
602   CD_track[nb_max_track].beg_min =
603     binbcd[bcdbin[CD_track[nb_max_track - 1].beg_min] + Min];
604   CD_track[nb_max_track].beg_sec =
605     binbcd[bcdbin[CD_track[nb_max_track - 1].beg_sec] + Sec];
606   CD_track[nb_max_track].beg_fra =
607     binbcd[bcdbin[CD_track[nb_max_track - 1].beg_fra] + Fra];
608 
609   CD_track[nb_max_track].type = 4;
610   CD_track[nb_max_track].beg_lsn =
611     msf2nb_sect (bcdbin[CD_track[nb_max_track].beg_min] -
612 		 bcdbin[CD_track[1].beg_min],
613 		 bcdbin[CD_track[nb_max_track].beg_sec] -
614 		 bcdbin[CD_track[1].beg_sec],
615 		 bcdbin[CD_track[nb_max_track].beg_fra] -
616 		 bcdbin[CD_track[1].beg_fra]);
617 
618   /* Thank to Nyef for having localised a little bug there */
619   switch (CD_emulation)
620     {
621     case 2:
622       CD_track[nb_max_track].length = filesize (iso_FILE) / 2048;
623       break;
624     case 3:
625       CD_track[nb_max_track].length = packed_iso_filesize / 2048;
626       break;
627     case 4:
628       CD_track[nb_max_track].length = 14000;
629       break;
630     default:
631       break;
632     }
633 
634   return;
635 }
636 
637 
638 void
read_sector_BIN(unsigned char * p,UInt32 sector)639 read_sector_BIN (unsigned char *p, UInt32 sector)
640 {
641   static int first_read = 1;
642   static long second_track_sector = 0;
643   int result;
644 
645 
646   if (first_read)
647     {
648       UChar found = 0, dummy;
649       int index_in_header = 0;
650       unsigned long position;
651 
652       fseek (iso_FILE, 0, SEEK_SET);
653 
654       while ((!found) && (!feof (iso_FILE)))
655 	{
656 	  dummy = getc (iso_FILE);
657 	  if (dummy == ISO_header[0])
658 	    {
659 	      position = ftell (iso_FILE);
660 	      index_in_header = 1;
661 	      while ((index_in_header < 0x800) &&
662 		     (getc (iso_FILE) == ISO_header[index_in_header++]));
663 
664 	      if (index_in_header == 0x800)
665 		{
666 		  found = 1;
667 		  second_track_sector = ftell (iso_FILE) - 0x800;
668 		}
669 
670 	      fseek (iso_FILE, position, SEEK_SET);
671 	    }
672 	}
673 
674       first_read = 0;
675 
676     }
677 
678 
679 
680   for (result = bcdbin[nb_max_track]; result > 0x01; result--)
681     {
682       if ((sector >= CD_track[binbcd[result]].beg_lsn) &&
683 	  (sector <= CD_track[binbcd[result]].beg_lsn +
684 	   CD_track[binbcd[result]].length))
685 	break;
686     }
687 
688   if (result != 0x02)
689     {
690       Log ("Read on non track 2\nTrack %d asked\nsector : 0x%x\n", result,
691 	   pce_cd_sectoraddy);
692       exit (-10);
693     }
694 
695 #ifndef FINAL_RELEASE
696   fprintf (stderr, "Loading sector n�%d.\n", pce_cd_sectoraddy);
697 #endif
698 
699   fseek (iso_FILE,
700 	 second_track_sector + (sector -
701 				CD_track[binbcd[result]].beg_lsn) * 2352,
702 	 SEEK_SET);
703   fread (p, 2048, 1, iso_FILE);
704 
705 }
706 
707 void
read_sector_ISQ(unsigned char * p,UInt32 sector)708 read_sector_ISQ (unsigned char *p, UInt32 sector)
709 {
710 
711 #ifdef ALLEGRO
712 
713   int result;
714   UInt32 dummy;
715 
716 /*
717 ####################################
718 ####################################
719 ####################################
720 ####################################
721 2KILL :: BEGIN
722 ####################################
723 ####################################
724 ####################################
725 ####################################
726 */
727 
728   for (result = bcdbin[nb_max_track]; result > 0x01; result--)
729     {
730       if ((sector >= CD_track[binbcd[result]].beg_lsn) &&
731 	  (sector <= CD_track[binbcd[result]].beg_lsn +
732 	   CD_track[binbcd[result]].length))
733 	break;
734     }
735 
736   if (result != 0x02)
737     {
738       Log ("Read on non track 2\nTrack %d asked\nsector : 0x%x\n", result,
739 	   pce_cd_sectoraddy);
740       exit (-10);
741     }
742 
743 #ifndef FINAL_RELEASE
744   fprintf (stderr, "Loading sector n�%d.\n", pce_cd_sectoraddy);
745 #endif
746 
747   dummy = (sector - CD_track[binbcd[result]].beg_lsn) * 2048;
748 
749   if (ISQ_position > dummy)
750     {
751       pack_fclose (packed_iso_FILE);
752       packed_iso_FILE = pack_fopen (ISO_filename, F_READ_PACKED);
753       pack_fseek (packed_iso_FILE, dummy);
754       ISQ_position = dummy;
755     }
756   else if (ISQ_position < dummy)
757     {
758       pack_fseek (packed_iso_FILE, dummy - ISQ_position);
759       ISQ_position = dummy;
760     }
761 
762   pack_fread (p, 2048, packed_iso_FILE);
763 
764   ISQ_position += 2048;
765 
766 #endif
767 /*
768 ####################################
769 ####################################
770 ####################################
771 ####################################
772 2KILL :: END
773 ####################################
774 ####################################
775 ####################################
776 ####################################
777 */
778 
779 }
780 
781 #define CD_BUF_LENGTH 8
782 UInt32 first_sector = 0;
783 
784 void
read_sector_CD(unsigned char * p,UInt32 sector)785 read_sector_CD (unsigned char *p, UInt32 sector)
786 {
787   int i;
788 #ifndef FINAL_RELEASE
789   Log ("Reading sector : %d\n", sector);
790 #endif
791 
792   if (cd_buf != NULL)
793     if ((sector >= first_sector) &&
794 				(sector <= first_sector + CD_BUF_LENGTH - 1))
795       {
796 				memcpy (p, cd_buf + 2048 * (sector - first_sector), 2048);
797 				return;
798 			}
799     else
800       {
801 				for (i = 0; i < CD_BUF_LENGTH; i++)
802 					osd_cd_read (cd_buf + 2048 * i, sector + i);
803 				first_sector = sector;
804 				memcpy (p, cd_buf, 2048);
805       }
806   else
807     {
808       cd_buf = (UChar *) malloc (CD_BUF_LENGTH * 2048);
809       for (i = 0; i < CD_BUF_LENGTH; i++)
810 				osd_cd_read (cd_buf + 2048 * i, sector + i);
811       first_sector = sector;
812       memcpy (p, cd_buf, 2048);
813     }
814 
815 }
816 
817 void
read_sector_ISO(unsigned char * p,UInt32 sector)818 read_sector_ISO (unsigned char *p, UInt32 sector)
819 {
820   int result;
821 
822   for (result = nb_max_track; result > 0x01; result--)
823     {
824       if ((sector >= CD_track[result].beg_lsn) &&
825 	  (sector <= CD_track[result].beg_lsn + CD_track[result].length))
826 	break;
827     }
828 
829 #ifndef FINAL_RELEASE
830   fprintf (stderr, "Loading sector n�%d.\n", pce_cd_sectoraddy);
831   Log
832     ("Loading sector n�%d.\nAX=%02x%02x\nBX=%02x%02x\nCX=%02x%02x\nDX=%02x%02x\n\n",
833      pce_cd_sectoraddy, RAM[0xf9], RAM[0xf8], RAM[0xfb], RAM[0xfa], RAM[0xfd],
834      RAM[0xfc], RAM[0xff], RAM[0xfe]);
835   Log("temp+2-5 = %x %x %x\ntemp + 1 = %02x\n",RAM[5], RAM[6], RAM[7], RAM[4]);
836   Log ("ISO : seek at %d\n", (sector - CD_track[result].beg_lsn) * 2048);
837   Log ("Track n�%d begin at %d\n", result, CD_track[result].beg_lsn);
838 #endif
839 
840   if (result != 0x02)
841     {
842       int i;
843 
844       Log ("Read on non track 2\nTrack %d asked\nsector : 0x%x\n", result,
845 	   pce_cd_sectoraddy);
846 
847       /* exit(-10);
848 
849        * Don't quit anymore but fill the reading buffer with garbage
850        * easily recognizable
851        */
852 
853       for (i = 0; i < 2048; i += 4)
854 				*(UInt32 *) & p[i] = 0xDEADBEEF;
855 
856       return;
857     }
858 
859   if (sector == CD_track[result].beg_lsn)
860     {				/* We're reading the first sector, the header */
861       if (force_header)
862 				{
863 					memcpy (p, ISO_header, 0x800);
864 					return;
865 				}
866     }
867 
868   fseek (iso_FILE, (sector - CD_track[result].beg_lsn) * 2048, SEEK_SET);
869   fread (p, 2048, 1, iso_FILE);
870 
871 }
872 
873 void
read_sector_dummy(unsigned char * p,UInt32 sector)874 read_sector_dummy (unsigned char *p, UInt32 sector)
875 {
876   return;
877 }
878 
879 void
pce_cd_read_sector(void)880 pce_cd_read_sector (void)
881 {
882   /* Avoid sound jiggling when accessing some sectors */
883   if (sound_driver == 1)
884     osd_snd_set_volume (0);
885 
886 #ifdef CD_DEBUG
887   Log ("Will read sectors using function #%d\n", CD_emulation);
888 
889   printf("Reading sector %d (in pce_cd_read_sector)\n", pce_cd_sectoraddy);
890 #endif
891 
892   (*read_sector_method[CD_emulation]) (cd_sector_buffer, pce_cd_sectoraddy);
893 
894   pce_cd_sectoraddy++;
895 
896 #if 0
897   for (result = 0; result < 2048; result++)
898     {
899       if ((result & 15) == 0)
900 				{
901 					fprintf (stderr, "%03x: ", result);
902 				}
903       fprintf (stderr, "%02x", cd_sector_buffer[result]);
904       if ((result & 15) == 15)
905 				{
906 					fprintf (stderr, "\n");
907 				}
908       else
909 				{
910 					fprintf (stderr, " ");
911 				}
912     }
913 #endif
914 
915 #ifndef FINAL_RELEASE
916 #if 0
917   {
918 
919     FILE *g = fopen ("read.cd", "at");
920     int result;
921 
922     fprintf (g, "\nsector #%x\n", pce_cd_sectoraddy - 1);
923 
924     for (result = 0; result < 2048; result++)
925       {
926 				if ((result & 15) == 0)
927 					{
928 						fprintf (g, "%03x: ", result);
929 					}
930 				fprintf (g, "%02x", cd_sector_buffer[result]);
931 				if ((result & 15) == 15)
932 					{
933 						fprintf (g, "\n");
934 					}
935 				else
936 					{
937 						fprintf (g, " ");
938 					}
939       }
940 
941     fclose (g);
942 
943   }
944 #endif
945 #endif
946 
947   pce_cd_read_datacnt = 2048;
948   cd_read_buffer = cd_sector_buffer;
949 
950   /* restore sound volume */
951   if (sound_driver == 1)
952     osd_snd_set_volume (0);
953 }
954 
955 void
issue_ADPCM_dma(void)956 issue_ADPCM_dma (void)
957 {
958 #ifndef FINAL_RELEASE
959   fprintf (stderr, "Will make DMA transfer\n");
960   Log ("ADPCM DMA will begin\n");
961 #endif
962 
963   while (cd_sectorcnt--)
964     {
965       memcpy (PCM + io.adpcm_dmaptr, cd_read_buffer, pce_cd_read_datacnt);
966       cd_read_buffer = NULL;
967       io.adpcm_dmaptr += pce_cd_read_datacnt;
968       pce_cd_read_datacnt = 0;
969       pce_cd_read_sector ();
970     }
971 
972   pce_cd_read_datacnt = 0;
973   pce_cd_adpcm_trans_done = 1;
974   cd_read_buffer = NULL;
975 }
976 
977 /*
978  *  convert logical_block_address to m-s-f_number (3 bytes only)
979  *  lifted from the cdrom test program in the Linux kernel docs.
980  *  hacked up to convert to BCD.
981  */
982 #ifndef LINUX
983 #define CD_MSF_OFFSET 150
984 #endif
985 
986 void
lba2msf(int lba,unsigned char * msf)987 lba2msf (int lba, unsigned char *msf)
988 {
989   lba += CD_MSF_OFFSET;
990   msf[0] = binbcd[lba / (CD_SECS * CD_FRAMES)];
991   lba %= CD_SECS * CD_FRAMES;
992   msf[1] = binbcd[lba / CD_FRAMES];
993   msf[2] = binbcd[lba % CD_FRAMES];
994 }
995 
996 
997 UInt32
msf2nb_sect(UChar min,UChar sec,UChar frm)998 msf2nb_sect (UChar min, UChar sec, UChar frm)
999 {
1000   UInt32 result = frm;
1001   result += sec * CD_FRAMES;
1002   result += min * CD_FRAMES * CD_SECS;
1003   return result;
1004 }
1005 
1006 void
nb_sect2msf(UInt32 lsn,UChar * min,UChar * sec,UChar * frm)1007 nb_sect2msf (UInt32 lsn, UChar * min, UChar * sec, UChar * frm)
1008 {
1009 
1010   (*frm) = lsn % CD_FRAMES;
1011   lsn /= CD_FRAMES;
1012   (*sec) = lsn % CD_SECS;
1013   (*min) = lsn / CD_SECS;
1014 
1015   return;
1016 }
1017 
1018 void
IO_write(UInt16 A,UChar V)1019 IO_write (UInt16 A, UChar V)
1020 {
1021   //printf("w%04x,%02x ",A&0x3FFF,V);
1022 
1023   if ((A >= 0x800) && (A < 0x1800)) // We keep the io buffer value
1024     io.io_buffer = V;
1025 
1026 #ifndef FINAL_RELEASE
1027   if ((A & 0x1F00) == 0x1A00)
1028     Log ("\nAC Write %02x at %04x\n", V, A);
1029 #endif
1030 
1031   switch (A & 0x1F00)
1032     {
1033     case 0x0000:		/* VDC */
1034       switch (A & 3)
1035 	{
1036 	case 0:
1037 	  io.vdc_reg = V & 31;
1038 	  return;
1039 	case 1:
1040 	  return;
1041 	case 2:
1042 	  //printf("vdc_l%d,%02x ",io.vdc_reg,V);
1043 	  switch (io.vdc_reg)
1044 	    {
1045 	    case VWR:		/* Write to video */
1046 	      io.vdc_ratch = V;
1047 	      return;
1048 	    case HDR:		/* Horizontal Definition */
1049 	      {
1050                 typeof (io.screen_w) old_value = io.screen_w;
1051                 io.screen_w = (V + 1) * 8;
1052 
1053                 if (io.screen_w == old_value)
1054                   break;
1055 
1056                 /* TODO: checking if needed, this could remove an ALLEGRO
1057                  * related piece of code
1058                  */
1059 #ifdef ALLEGRO
1060                 clear (screen);
1061 #endif
1062 
1063                 // (*init_normal_mode[video_driver]) ();
1064 #if defined(NEW_GFX_ENGINE)
1065                 gfx_need_video_mode_change = 1;
1066 #else
1067                 (*osd_gfx_driver_list[video_driver].mode) ();
1068 #endif
1069 
1070 
1071                 {
1072                   UInt32 x, y = (WIDTH - io.screen_w) / 2 - 512 * WIDTH;
1073                   for (x = 0; x < 1024; x++)
1074                     {
1075                       spr_init_pos[x] = y;
1076                       y += WIDTH;
1077                     }
1078                 }
1079 	      }
1080 	      break;
1081 
1082 	    case MWR:		/* size of the virtual background screen */
1083 	      {
1084                 static UChar bgw[] = { 32, 64, 128, 128 };
1085                 io.bg_h = (V & 0x40) ? 64 : 32;
1086                 io.bg_w = bgw[(V >> 4) & 3];
1087 	      }
1088 	      break;
1089 
1090 	    case BYR:		/* Vertical screen offset */
1091 
1092 				/*
1093 				if (io.VDC[BYR].B.l == V)
1094 					return;
1095 				*/
1096 
1097 #if defined(NEW_GFX_ENGINE)
1098               save_gfx_context(0);
1099 #endif
1100 
1101 	      if (!scroll)
1102                 {
1103                   oldScrollX = ScrollX;
1104                   oldScrollY = ScrollY;
1105                   oldScrollYDiff = ScrollYDiff;
1106                 }
1107 	      io.VDC[BYR].B.l = V;
1108 	      scroll = 1;
1109 	      ScrollYDiff = scanline - 1;
1110 #if defined(NEW_GFX_ENGINE)
1111               ScrollYDiff -= io.VDC[VPR].B.h + io.VDC[VPR].B.l;
1112 #endif
1113 
1114 #if defined(GFX_DEBUG)
1115               gfx_debug_printf("ScrollY = %d (l)", ScrollY);
1116 #endif
1117 	      return;
1118 	    case BXR:		/* Horizontal screen offset */
1119 
1120 				/*
1121 				if (io.VDC[BXR].B.l == V)
1122 					return;
1123 				*/
1124 
1125 #if defined(NEW_GFX_ENGINE)
1126               save_gfx_context(0);
1127 #endif
1128 
1129 	      if (!scroll)
1130                 {
1131                   oldScrollX = ScrollX;
1132                   oldScrollY = ScrollY;
1133                   oldScrollYDiff = ScrollYDiff;
1134                 }
1135 	      io.VDC[BXR].B.l = V;
1136 	      scroll = 1;
1137 	      return;
1138 
1139 #if defined(NEW_GFX_ENGINE)
1140 
1141             case CR:
1142               if (io.VDC[io.vdc_reg].B.l == V)
1143                 return;
1144               save_gfx_context(0);
1145               io.VDC[io.vdc_reg].B.l = V;
1146               return;
1147 
1148             case VCR:
1149               io.VDC[io.vdc_reg].B.l = V;
1150               gfx_need_video_mode_change = 1;
1151               return;
1152 
1153             case HSR:
1154               io.VDC[io.vdc_reg].B.l = V;
1155               gfx_need_video_mode_change = 1;
1156               return;
1157 
1158             case VPR:
1159               io.VDC[io.vdc_reg].B.l = V;
1160               gfx_need_video_mode_change = 1;
1161               return;
1162 
1163 	    case VDW:
1164               io.VDC[io.vdc_reg].B.l = V;
1165               gfx_need_video_mode_change = 1;
1166               return;
1167 
1168 #endif
1169 	    }
1170 
1171 	  io.VDC[io.vdc_reg].B.l = V;
1172 	  /* all others reg just need to get the value, without
1173 	     additional stuff */
1174 
1175 
1176 #if defined(GFX_DEBUG) && !defined(FINAL_RELEASE)
1177           gfx_debug_printf("VDC[%02x]=0x%02x", io.vdc_reg, V);
1178 #endif
1179 
1180 #ifndef FINAL_RELEASE
1181 	  if (io.vdc_reg > 19)
1182 	    {
1183 	      fprintf (stderr, "ignore write lo vdc%d,%02x\n", io.vdc_reg, V);
1184 	    }
1185 #endif
1186 
1187 	  return;
1188 	case 3:
1189 	  switch (io.vdc_reg)
1190 	    {
1191 	    case VWR:		/* Write to mem */
1192 	      /* Writing to hi byte actually perform the action */
1193 	      VRAM[io.VDC[MAWR].W * 2] = io.vdc_ratch;
1194 	      VRAM[io.VDC[MAWR].W * 2 + 1] = V;
1195 
1196 	      vchange[io.VDC[MAWR].W / 16] = 1;
1197 	      vchanges[io.VDC[MAWR].W / 64] = 1;
1198 
1199 	      io.VDC[MAWR].W += io.vdc_inc;
1200 
1201               /* vdc_ratch shouldn't be reset between writes */
1202 	      // io.vdc_ratch = 0;
1203 	      return;
1204 
1205 #if defined(NEW_GFX_ENGINE)
1206 
1207             case VCR:
1208               io.VDC[io.vdc_reg].B.h = V;
1209               gfx_need_video_mode_change = 1;
1210               return;
1211 
1212             case HSR:
1213               io.VDC[io.vdc_reg].B.h = V;
1214               gfx_need_video_mode_change = 1;
1215               return;
1216 
1217             case VPR:
1218               io.VDC[io.vdc_reg].B.h = V;
1219               gfx_need_video_mode_change = 1;
1220               return;
1221 
1222 	    case VDW:		/* screen height */
1223               io.VDC[io.vdc_reg].B.h = V;
1224               gfx_need_video_mode_change = 1;
1225               return;
1226 #else
1227             case VDW:
1228 	      {
1229 		typeof (io.screen_h) temp_h = io.screen_h;
1230 		io.VDC[VDW].B.h = V;
1231 
1232 		io.screen_h = (io.VDC[VDW].W & 511) + 1;
1233 
1234 		MaxLine = io.screen_h - 1;
1235 
1236 		if (temp_h == io.screen_h)
1237 		  return;
1238 		/* TODO: check utility here too, cf upper */
1239 
1240 #ifdef ALLEGRO
1241 		clear (screen);
1242 #endif
1243 
1244 		// (*init_normal_mode[video_driver]) ();
1245 		(*osd_gfx_driver_list[video_driver].mode) ();
1246 
1247 	      }
1248 	      return;
1249 
1250 #endif
1251 
1252 	    case LENR:		/* DMA transfert */
1253 
1254 	      io.VDC[LENR].B.h = V;
1255 
1256               { // black-- 's code
1257 
1258                 int sourcecount = (io.VDC[DCR].W & 8) ? -1 : 1;
1259                 int destcount = (io.VDC[DCR].W & 4) ? -1 : 1;
1260 
1261                 int source = io.VDC[SOUR].W * 2;
1262                 int dest = io.VDC[DISTR].W * 2;
1263 
1264                 int i;
1265 
1266                 for (i = 0; i < (io.VDC[LENR].W + 1) * 2; i++)
1267                   {
1268                     *(VRAM + dest) = *(VRAM + source);
1269                     dest += destcount;
1270                     source += sourcecount;
1271                   }
1272 
1273                 /*
1274                   io.VDC[SOUR].W = source;
1275                   io.VDC[DISTR].W = dest;
1276                 */
1277                 // Erich Kitzmuller fix follows
1278                 io.VDC[SOUR].W = source / 2;
1279                 io.VDC[DISTR].W = dest / 2;
1280 
1281               }
1282 
1283               io.VDC[LENR].W = 0xFFFF;
1284 
1285               memset(vchange, 1, VRAMSIZE / 32);
1286               memset(vchanges,1, VRAMSIZE / 128);
1287 
1288 
1289               /* TODO: check whether this flag can be ignored */
1290               io.vdc_status |= VDC_DMAfinish;
1291 
1292 	      return;
1293 
1294 	    case CR:		/* Auto increment size */
1295 	      {
1296                 static UChar incsize[] = { 1, 32, 64, 128 };
1297                 /*
1298                   if (io.VDC[CR].B.h == V)
1299                   return;
1300                 */
1301 #if defined(NEW_GFX_ENGINE)
1302                 save_gfx_context(0);
1303 #endif
1304                 io.vdc_inc = incsize[(V >> 3) & 3];
1305                 io.VDC[CR].B.h = V;
1306 	      }
1307 	      break;
1308 	    case HDR:		/* Horizontal display end */
1309 	      /* TODO : well, maybe we should implement it */
1310 	      //io.screen_w = (io.VDC_ratch[HDR]+1)*8;
1311 	      //TRACE0("HDRh\n");
1312 #if defined(GFX_DEBUG)
1313               gfx_debug_printf("VDC[HDR].h = %d", V);
1314 #endif
1315 	      break;
1316 
1317 	    case BYR:		/* Vertical screen offset */
1318 
1319 				/*
1320 				if (io.VDC[BYR].B.h == (V & 1))
1321 					return;
1322 				*/
1323 
1324 #if defined(NEW_GFX_ENGINE)
1325               save_gfx_context(0);
1326 #endif
1327 
1328 	      if (!scroll)
1329 		{
1330 		  oldScrollX = ScrollX;
1331 		  oldScrollY = ScrollY;
1332 		  oldScrollYDiff = ScrollYDiff;
1333 		}
1334 	      io.VDC[BYR].B.h = V & 1;
1335 	      scroll = 1;
1336 	      ScrollYDiff = scanline - 1;
1337 #if defined(NEW_GFX_ENGINE)
1338               ScrollYDiff -= io.VDC[VPR].B.h + io.VDC[VPR].B.l;
1339 #if defined(GFX_DEBUG)
1340               if (ScrollYDiff < 0)
1341                 gfx_debug_printf("ScrollYDiff went negative when substraction VPR.h/.l (%d,%d)", io.VDC[VPR].B.h, io.VDC[VPR].B.l);
1342 #endif
1343 #endif
1344 
1345 #if defined(GFX_DEBUG)
1346               gfx_debug_printf("ScrollY = %d (h)", ScrollY);
1347 #endif
1348 
1349 	      return;
1350 	    case SATB:		/* DMA from VRAM to SATB */
1351 	      io.VDC[SATB].B.h = V;
1352 	      io.vdc_satb = 1;
1353 	      io.vdc_status &= ~VDC_SATBfinish;
1354 	      return;
1355 	    case BXR:		/* Horizontal screen offset */
1356 
1357               if (io.VDC[BXR].B.h == (V & 3))
1358                 return;
1359 
1360 #if defined(NEW_GFX_ENGINE)
1361               save_gfx_context(0);
1362 #endif
1363 
1364 	      if (!scroll)
1365 		{
1366 		  oldScrollX = ScrollX;
1367 		  oldScrollY = ScrollY;
1368 		  oldScrollYDiff = ScrollYDiff;
1369 		}
1370 	      io.VDC[BXR].B.h = V & 3;
1371 	      scroll = 1;
1372 	      return;
1373 	    }
1374 	  io.VDC[io.vdc_reg].B.h = V;
1375 
1376 #ifndef FINAL_RELEASE
1377 	  if (io.vdc_reg > 19)
1378 	    {
1379 	      fprintf (stderr, "ignore write hi vdc%d,%02x\n", io.vdc_reg, V);
1380 	    }
1381 #endif
1382 
1383 	  return;
1384 	}
1385       break;
1386 
1387     case 0x0400:		/* VCE */
1388       switch (A & 7)
1389 	{
1390 	case 0:
1391 	  /*TRACE("VCE 0, V=%X\n", V); */
1392           return;
1393 
1394 	  /* Choose color index */
1395 	case 2:
1396 	  io.vce_reg.B.l = V;
1397 	  return;
1398 	case 3:
1399 	  io.vce_reg.B.h = V & 1;
1400 	  return;
1401 
1402 	  /* Set RGB components for current choosen color */
1403 	case 4:
1404 	  io.VCE[io.vce_reg.W].B.l = V;
1405 	  {
1406 	    UChar c;
1407 	    int i, n;
1408 	    n = io.vce_reg.W;
1409 	    c = io.VCE[n].W >> 1;
1410 	    if (n == 0)
1411 	      {
1412 		for (i = 0; i < 256; i += 16)
1413 		  Pal[i] = c;
1414 	      }
1415 	    else if (n & 15)
1416 	      Pal[n] = c;
1417 	  }
1418 	  return;
1419 
1420 	case 5:
1421 	  io.VCE[io.vce_reg.W].B.h = V;
1422 	  {
1423 	    UChar c;
1424 	    int i, n;
1425 	    n = io.vce_reg.W;
1426 	    c = io.VCE[n].W >> 1;
1427 	    if (n == 0)
1428 	      {
1429 		for (i = 0; i < 256; i += 16)
1430 		  Pal[i] = c;
1431 	      }
1432 	    else if (n & 15)
1433 	      Pal[n] = c;
1434 	  }
1435 	  io.vce_reg.W = (io.vce_reg.W + 1) & 0x1FF;
1436 	  return;
1437 	}
1438       break;
1439 
1440 
1441     case 0x0800:		/* PSG */
1442 
1443       switch (A & 15)
1444 	{
1445 
1446 	  /* Select PSG channel */
1447 	case 0:
1448 	  io.psg_ch = V & 7;
1449 	  return;
1450 
1451 	  /* Select global volume */
1452 	case 1:
1453 	  io.psg_volume = V;
1454 	  return;
1455 
1456 	/* Frequency setting, 8 lower bits */
1457 	case 2:
1458 	  io.PSG[io.psg_ch][2] = V;
1459 	  break;
1460 
1461 	/* Frequency setting, 4 upper bits */
1462 	case 3:
1463 	  io.PSG[io.psg_ch][3] = V & 15;
1464 	  break;
1465 
1466 	case 4:
1467 	  io.PSG[io.psg_ch][4] = V;
1468 #ifdef SOUND_DEBUG
1469 	  if ((V & 0xC0) == 0x40)
1470             io.PSG[io.psg_ch][PSG_DATA_INDEX_REG] = 0;
1471 #endif
1472 	  break;
1473 
1474 	  /* Set channel specific volume */
1475 	case 5:
1476 	  io.PSG[io.psg_ch][5] = V;
1477 	  break;
1478 
1479 	  /* Put a value into the waveform or direct audio buffers */
1480 	case 6:
1481           if (io.PSG[io.psg_ch][PSG_DDA_REG] & PSG_DDA_DIRECT_ACCESS)
1482             {
1483               io.psg_da_data[io.psg_ch][io.psg_da_index[io.psg_ch]] = V;
1484               io.psg_da_index[io.psg_ch] = (io.psg_da_index[io.psg_ch] + 1) & 0x3FF;
1485               if (io.psg_da_count[io.psg_ch]++ > (PSG_DIRECT_ACCESS_BUFSIZE - 1))
1486                 {
1487                   if (!io.psg_channel_disabled[io.psg_ch])
1488                     printf("Audio being stuffed into the direct access buffer faster than it's being played.\n");
1489                   io.psg_da_count[io.psg_ch] = 0;
1490                 }
1491             }
1492           else
1493             {
1494               io.wave[io.psg_ch][io.PSG[io.psg_ch][PSG_DATA_INDEX_REG]] = V;
1495               io.PSG[io.psg_ch][PSG_DATA_INDEX_REG] = (io.PSG[io.psg_ch][PSG_DATA_INDEX_REG] + 1) & 0x1F;
1496             }
1497 	  break;
1498 
1499 	case 7:
1500 	  io.PSG[io.psg_ch][7] = V;
1501 	  break;
1502 
1503 	case 8:
1504 	  io.psg_lfo_freq = V;
1505 	  break;
1506 
1507 	case 9:
1508 	  io.psg_lfo_ctrl = V;
1509 	  break;
1510 
1511 #ifdef EXTRA_CHECKING
1512 	default:
1513 	  fprintf (stderr, "ignored PSG write\n");
1514 #endif
1515 	}
1516       return;
1517 
1518     case 0x0c00:		/* timer */
1519       //TRACE("Timer Access: A=%X,V=%X\n", A, V);
1520       switch (A & 1)
1521 	{
1522 	case 0:
1523 	  io.timer_reload = V & 127;
1524 	  return;
1525 	case 1:
1526 	  V &= 1;
1527 	  if (V && !io.timer_start)
1528 	    io.timer_counter = io.timer_reload;
1529 	  io.timer_start = V;
1530 	  return;
1531 	}
1532       break;
1533 
1534     case 0x1000:		/* joypad */
1535 //        TRACE("V=%02X\n", V);
1536       io.joy_select = V & 1;
1537       //io.joy_select = V;
1538       if (V & 2)
1539 	io.joy_counter = 0;
1540       return;
1541 
1542     case 0x1400:		/* IRQ */
1543       switch (A & 15)
1544 	{
1545 	case 2:
1546 	  io.irq_mask = V;	/*TRACE("irq_mask = %02X\n", V); */
1547 	  return;
1548 	case 3:
1549 	  io.irq_status = (io.irq_status & ~TIRQ) | (V & 0xF8);
1550 	  return;
1551 	}
1552       break;
1553 
1554     case 0x1A00:
1555       {
1556 
1557 	if ((A & 0x1AF0) == 0x1AE0)
1558 	  {
1559 	    switch (A & 15)
1560 	      {
1561 	      case 0:
1562 		io.ac_shift = (io.ac_shift & 0xffffff00) | V;
1563 		break;
1564 	      case 1:
1565 		io.ac_shift = (io.ac_shift & 0xffff00ff) | (V << 8);
1566 		break;
1567 	      case 2:
1568 		io.ac_shift = (io.ac_shift & 0xff00ffff) | (V << 16);
1569 		break;
1570 	      case 3:
1571 		io.ac_shift = (io.ac_shift & 0x00ffffff) | (V << 24);
1572 		break;
1573 	      case 4:
1574 		io.ac_shiftbits = V & 0x0f;
1575 		if (io.ac_shiftbits != 0)
1576 		  {
1577 		    if (io.ac_shiftbits < 8)
1578 		      {
1579 			io.ac_shift <<= io.ac_shiftbits;
1580 		      }
1581 		    else
1582 		      {
1583 			io.ac_shift >>= (16 - io.ac_shiftbits);
1584 		      }
1585 		  }
1586 	      default:
1587 		break;
1588 	      }
1589 	    return;
1590 	  }
1591 	else
1592 	  {
1593 	    UChar ac_port = (A >> 4) & 3;
1594 	    switch (A & 15)
1595 	      {
1596 	      case 0:
1597 	      case 1:
1598 
1599 		if (io.ac_control[ac_port] & AC_USE_OFFSET)
1600 		  {
1601 #if defined(CD_DEBUG)
1602 		    // fprintf(stderr,"Write %d to 0x%04X (base + offset)\n",V,
1603 		    //           io.ac_offset[ac_port] + io.ac_base[ac_port]);
1604 #endif
1605 		    // Log("Write %d to 0x%04X (base + offset)\n",V,
1606 		    //           io.ac_offset[ac_port] + io.ac_base[ac_port]);
1607 		    ac_extra_mem[((io.ac_base[ac_port] +
1608 				   io.ac_offset[ac_port]) & 0x1fffff)] = V;
1609 		  }
1610 		else
1611 		  {
1612 #if defined(CD_DEBUG)
1613 		    // fprintf(stderr, "Write %d to 0x%04X (base)\n",V, io.ac_base[ac_port]);
1614 #endif
1615 		    // Log("Write %d to 0x%04X (base)\n",V, io.ac_base[ac_port]);
1616 		    ac_extra_mem[((io.ac_base[ac_port]) & 0x1fffff)] = V;
1617 		  }
1618 
1619 		if (io.ac_control[ac_port] & AC_ENABLE_INC)
1620 		  {
1621 		    if (io.ac_control[ac_port] & AC_INCREMENT_BASE)
1622 		      io.ac_base[ac_port] =
1623 			(io.ac_base[ac_port] +
1624 			 io.ac_incr[ac_port]) & 0xffffff;
1625 		    else
1626 		      io.ac_offset[ac_port] =
1627 			(io.ac_offset[ac_port] +
1628 			 io.ac_incr[ac_port]) & 0xffffff;
1629 		  }
1630 
1631 		return;
1632 	      case 2:
1633 		io.ac_base[ac_port] = (io.ac_base[ac_port] & 0xffff00) | V;
1634 		return;
1635 	      case 3:
1636 		io.ac_base[ac_port] =
1637 		  (io.ac_base[ac_port] & 0xff00ff) | (V << 8);
1638 		return;
1639 	      case 4:
1640 		io.ac_base[ac_port] =
1641 		  (io.ac_base[ac_port] & 0x00ffff) | (V << 16);
1642 		return;
1643 	      case 5:
1644 		io.ac_offset[ac_port] = (io.ac_offset[ac_port] & 0xff00) | V;
1645 		return;
1646 	      case 6:
1647 		io.ac_offset[ac_port] =
1648 		  (io.ac_offset[ac_port] & 0x00ff) | (V << 8);
1649 		if (io.ac_control[ac_port] & (AC_ENABLE_OFFSET_BASE_6))
1650 		  io.ac_base[ac_port] =
1651 		    (io.ac_base[ac_port] + io.ac_offset[ac_port]) & 0xffffff;
1652 		return;
1653 	      case 7:
1654 		io.ac_incr[ac_port] = (io.ac_incr[ac_port] & 0xff00) | V;
1655 		return;
1656 	      case 8:
1657 		io.ac_incr[ac_port] =
1658 		  (io.ac_incr[ac_port] & 0x00ff) | (V << 8);
1659 		return;
1660 	      case 9:
1661 		io.ac_control[ac_port] = V;
1662 		return;
1663 	      case 0xa:
1664 		if ((io.ac_control[ac_port]
1665                     & (AC_ENABLE_OFFSET_BASE_A | AC_ENABLE_OFFSET_BASE_6))
1666                     == (AC_ENABLE_OFFSET_BASE_A | AC_ENABLE_OFFSET_BASE_6))
1667 		  io.ac_base[ac_port] =
1668 		    (io.ac_base[ac_port] + io.ac_offset[ac_port]) & 0xffffff;
1669 		return;
1670 	      default:
1671 		Log ("\nUnknown AC write %d into 0x%04X\n", V, A);
1672 	      }
1673 
1674 	  }
1675       }
1676       break;
1677 
1678     case 0x1800:		/* CD-ROM extention */
1679 #if defined(BSD_CD_HARDWARE_SUPPORT)
1680       pce_cd_handle_write_1800(A, V);
1681 #else
1682       gpl_pce_cd_handle_write_1800(A, V);
1683 #endif
1684       break;
1685     }
1686 #ifndef FINAL_RELEASE
1687   fprintf (stderr,
1688 	   "ignore I/O write %04x,%02x\tBase adress of port %X\nat PC = %04X\n",
1689 	   A, V, A & 0x1CC0,
1690 #ifdef KERNEL_DS
1691 	   reg_pc);
1692 #else
1693 	   M.PC.W);
1694 #endif
1695 
1696 #endif
1697 //      DebugDumpTrace(4, TRUE);
1698 }
1699 
1700 #if !defined(NEW_GFX_ENGINE)
1701 
1702 #ifndef KERNEL_DS
1703 
1704 /* write */
1705 M6502 M;
1706 
1707 
1708 UChar
Loop6502(M6502 * R)1709 Loop6502 (M6502 * R)
1710 #else
1711 UChar
1712 Loop6502 ()
1713 #endif
1714 {
1715   static double lasttime = 0, lastcurtime = 0, frametime = 0.1;
1716 
1717   static int UCount = 0;
1718   static int prevline;
1719   int dispmin, dispmax;
1720   int ret;
1721 
1722   dispmin = 0;
1723 /*
1724     (MaxLine - MinLine >
1725      MAXDISP ? MinLine + ((MaxLine - MinLine - MAXDISP + 1) >> 1) : MinLine);
1726 */
1727   dispmax = 242;
1728 /*
1729     (MaxLine - MinLine >
1730      MAXDISP ? MaxLine - ((MaxLine - MinLine - MAXDISP + 1) >> 1) : MaxLine);
1731 */
1732 
1733   scanline = (scanline + 1) % scanlines_per_frame;
1734 
1735   ret = INT_NONE;
1736 
1737 #warning "Check if this doesn t create problems in some games"
1738   // io.vdc_status &= ~VDC_RasHit;
1739   io.vdc_status &= ~(VDC_RasHit | VDC_SATBfinish);
1740 
1741   if (scanline > MaxLine)
1742     io.vdc_status |= VDC_InVBlank;
1743 //      if (scanline==MinLine+scanlines_per_frame-1)
1744 //      else
1745   if (scanline == MinLine)
1746     {
1747       io.vdc_status &= ~VDC_InVBlank;
1748       prevline = dispmin;
1749       ScrollYDiff = 0;
1750       oldScrollYDiff = 0;
1751 //              if (io.vdc_iswrite_h)
1752 //              {
1753 //                      io.vdc_iswrite_h = 0;
1754 //                      ScrollY = io.VDC[BYR].W;
1755 //              }
1756 //              TRACE("\nFirstLine\n");
1757     }
1758   else if (scanline == MaxLine)
1759     {
1760       if (CheckSprites ())
1761         io.vdc_status |= VDC_SpHit;
1762       else
1763         io.vdc_status &= ~VDC_SpHit;
1764 
1765       if (UCount)
1766         UCount--;
1767       else
1768         {
1769 
1770           if (SpriteON && SPONSwitch)
1771             RefreshSpriteExact (prevline, dispmax, 0);
1772           RefreshLine (prevline, dispmax);
1773           // RefreshLine (prevline, dispmax - 1);
1774           if (SpriteON && SPONSwitch)
1775             RefreshSpriteExact (prevline, dispmax, 1);
1776           prevline = dispmax;
1777           UCount = UPeriod;
1778           RefreshScreen ();
1779         }
1780     }
1781   if (scanline >= MinLine && scanline <= MaxLine)
1782     {
1783       if (scanline == (io.VDC[RCR].W & 1023) - 64)
1784         {
1785           if (RasHitON && !UCount && dispmin <= scanline
1786               && scanline <= dispmax)
1787             {
1788               if (SpriteON && SPONSwitch)
1789                 RefreshSpriteExact (prevline - 0, scanline, 0);
1790               RefreshLine (prevline - 0, scanline - 1);
1791               if (SpriteON && SPONSwitch)
1792                 RefreshSpriteExact (prevline - 0, scanline, 1);
1793               prevline = scanline;
1794             }
1795           io.vdc_status |= VDC_RasHit;
1796           if (RasHitON)
1797             {
1798               //TRACE("rcr=%d\n", scanline);
1799               ret = INT_IRQ;
1800             }
1801         }
1802       else if (scroll)
1803         {
1804           if (scanline - 1 > prevline && !UCount)
1805             {
1806               int tmpScrollX, tmpScrollY, tmpScrollYDiff;
1807               tmpScrollX = ScrollX;
1808               tmpScrollY = ScrollY;
1809               tmpScrollYDiff = ScrollYDiff;
1810               ScrollX = oldScrollX;
1811               ScrollY = oldScrollY;
1812               ScrollYDiff = oldScrollYDiff;
1813               if (SpriteON && SPONSwitch)
1814                 RefreshSpriteExact (prevline, scanline - 1, 0);
1815 
1816               RefreshLine (prevline, scanline - 2);
1817               if (SpriteON && SPONSwitch)
1818                 RefreshSpriteExact (prevline, scanline - 1, 1);
1819               prevline = scanline - 1;
1820               ScrollX = tmpScrollX;
1821               ScrollY = tmpScrollY;
1822               ScrollYDiff = tmpScrollYDiff;
1823             }
1824         }
1825     }
1826   else
1827     {
1828       int rcr = (io.VDC[RCR].W & 1023) - 64;
1829       if (scanline == rcr)
1830         {
1831           //ScrollYDiff = scanline;
1832           if (RasHitON)
1833             {
1834               //TRACE("rcr=%d\n", scanline);
1835               io.vdc_status |= VDC_RasHit;
1836               ret = INT_IRQ;
1837             }
1838         }
1839     }
1840   scroll = 0;
1841   if (scanline == MaxLine + 1)
1842     {
1843 
1844       if (osd_keyboard ())
1845         return INT_QUIT;
1846 
1847 #if defined(GTK)
1848       while (gtk_events_pending())
1849       {
1850         if (gtk_main_iteration())
1851         {
1852         	return INT_QUIT;
1853         }
1854       }
1855 #endif
1856 
1857       wait_next_vsync();
1858 
1859       /* VRAM to SATB DMA */
1860       if (io.vdc_satb == 1 || io.VDC[DCR].W & 0x0010)
1861         {
1862 #if defined(WORDS_BIGENDIAN)
1863           swab(VRAM + io.VDC[SATB].W * 2, SPRAM, 64 * 8);
1864 #else
1865           memcpy (SPRAM, VRAM + io.VDC[SATB].W * 2, 64 * 8);
1866 #endif
1867           io.vdc_satb = 1;
1868           io.vdc_status &= ~VDC_SATBfinish;
1869         }
1870 
1871       if (ret == INT_IRQ)
1872         io.vdc_pendvsync = 1;
1873       else
1874         {
1875           //io.vdc_status|=VDC_InVBlank;
1876           if (VBlankON)
1877             {
1878               ret = INT_IRQ;
1879             }
1880         }
1881     }
1882   else if (scanline == min (MaxLine + 5, scanlines_per_frame - 1))
1883     {
1884       if (io.vdc_satb)
1885         {
1886           io.vdc_status |= VDC_SATBfinish;
1887           io.vdc_satb = 0;
1888           if (SATBIntON)
1889             {
1890               ret = INT_IRQ;
1891             }
1892           /* } else {
1893           io.vdc_status&=~VDC_SATBfinish;
1894           io.vdc_satb = 0;
1895           */
1896         }
1897     }
1898   else if (io.vdc_pendvsync && ret != INT_IRQ)
1899     {
1900       io.vdc_pendvsync = 0;
1901       //io.vdc_status|=VDC_InVBlank;
1902       if (VBlankON)
1903         {
1904           //TRACE("vsync=%d\n", scanline);
1905           ret = INT_IRQ;
1906         }
1907     }
1908   if (ret == INT_IRQ)
1909     {
1910       if (!(io.irq_mask & IRQ1))
1911         {
1912           io.irq_status |= IRQ1;
1913           return ret;
1914         }
1915     }
1916   return INT_NONE;
1917 }
1918 
1919 #endif
1920 
1921 UChar
TimerInt()1922 TimerInt ()
1923 {
1924   if (io.timer_start)
1925     {
1926       io.timer_counter--;
1927       if (io.timer_counter > 128)
1928 	{
1929 	  io.timer_counter = io.timer_reload;
1930 
1931 	  if (!(io.irq_mask & TIRQ))
1932 	    {
1933 	      io.irq_status |= TIRQ;
1934 	      return INT_TIMER;
1935 	    }
1936 
1937 	}
1938     }
1939   return INT_NONE;
1940 }
1941 
1942 #ifdef ALLEGRO
1943 
1944 #ifdef EXTERNAL_DAT
1945 
1946 #define LOAD_INTEGRATED_SYS_FILE ROM_size = 48; ROM = malloc(48*0x2000 + 512 ); memcpy(ROM,datafile[Built_in_cdsystem].dat,48*0x2000 + 512); ROM += 512; builtin_system_used=1; return 0;
1947 
1948 #else
1949 
1950 #define LOAD_INTEGRATED_SYS_FILE ROM_size = 48; ROM = malloc(48*0x2000 + 512 ); memcpy(ROM,data[Built_in_cdsystem].dat,48*0x2000 + 512); ROM += 512; builtin_system_used=1; return 0;
1951 
1952 #endif
1953 
1954 #else
1955 
1956 #define LOAD_INTEGRATED_SYS_FILE return search_syscard();
1957 
1958 #endif
1959 
1960 static char syscard_filename[PATH_MAX];
1961 
1962 /*****************************************************************************
1963 
1964     Function: search_possible_syscard
1965 
1966     Description: Search for a system card rom
1967     Parameters: none
1968     Return: NULL if none found, else a pointer to a static area containing
1969               its name
1970 
1971 *****************************************************************************/
1972 char*
search_possible_syscard()1973 search_possible_syscard()
1974 {
1975   FILE* f;
1976 
1977 #define POSSIBLE_LOCATION_COUNT 5
1978   const char* POSSIBLE_LOCATION[POSSIBLE_LOCATION_COUNT] = {
1979     "./","../","/usr/local/lib/hugo/","/usr/lib/hugo/","c:/"
1980   };
1981 
1982 #define POSSIBLE_FILENAME_COUNT  4
1983   const char* POSSIBLE_FILENAME[POSSIBLE_FILENAME_COUNT] = {
1984     "syscard.pce","syscard3.pce","syscard30.pce","cd-rom~1.pce"
1985   };
1986 
1987   int location, filename;
1988   char temp_buffer[PATH_MAX];
1989 
1990   if ((cdsystem_path != NULL) && (strcmp(cdsystem_path, "")))
1991     {
1992       Log("Testing syscard location : %s\n",cdsystem_path);
1993       if ((f = fopen(cdsystem_path,"rb")) != NULL)
1994         {
1995 	  fclose(f);
1996 	  return cdsystem_path;
1997 	}
1998     }
1999 
2000 
2001   for (location = 0; location <= POSSIBLE_LOCATION_COUNT; location++)
2002     for (filename = 0; filename < POSSIBLE_FILENAME_COUNT; filename++)
2003       {
2004 
2005         if (location < POSSIBLE_LOCATION_COUNT)
2006           strcpy(temp_buffer, POSSIBLE_LOCATION[location]);
2007         else
2008           strcpy(temp_buffer, short_exe_name);
2009 
2010         strcat(temp_buffer, POSSIBLE_FILENAME[filename]);
2011         Log("Testing syscard location : %s\n",temp_buffer);
2012         if ((f = fopen(temp_buffer,"rb")) != NULL)
2013           {
2014             fclose(f);
2015 	    strncpy(syscard_filename, temp_buffer, sizeof(syscard_filename));
2016 	    return syscard_filename;
2017           }
2018       }
2019   return NULL;
2020 }
2021 
2022 /*****************************************************************************
2023 
2024     Function: search_syscard
2025 
2026     Description: Search for a system card rom
2027     Parameters: none
2028     Return: -1 on error else 0
2029              set true_file_name
2030 
2031 *****************************************************************************/
2032 SInt32
search_syscard()2033 search_syscard()
2034 {
2035   char* syscard_location;
2036 
2037   syscard_location = search_possible_syscard();
2038 
2039   if (NULL == syscard_location)
2040     {
2041       return -1;
2042     }
2043   else
2044     {
2045       int CD_emulation_bak = CD_emulation;
2046       int return_value;
2047 
2048       CD_emulation = 0;
2049       return_value = CartLoad(cdsystem_path);
2050       CD_emulation = CD_emulation_bak;
2051       return return_value;
2052     }
2053 
2054 }
2055 
2056 /*****************************************************************************
2057 
2058     Function: CartLoad
2059 
2060     Description: load a card
2061     Parameters: char* name (the filename to load)
2062     Return: -1 on error else 0
2063                  set true_file_name or builtin_system
2064 
2065 *****************************************************************************/
2066 SInt32
CartLoad(char * name)2067 CartLoad (char *name)
2068 {
2069   FILE *fp = NULL;
2070   int fsize;
2071 #ifdef MSDOS
2072   char tmp_path[80];
2073 #endif
2074 
2075 	Log("Trying to load %s\n", name);
2076 
2077   if (CD_emulation == 1)
2078     {
2079 
2080 /*
2081  *       CD_emulation = 0;
2082  *
2083  *       CartLoad("h:/jeu/pce/cd_ge_93.pce");
2084  *
2085  *       CD_emulation = 1;
2086  *
2087  *       return 0;
2088  */
2089       LOAD_INTEGRATED_SYS_FILE;
2090 
2091     }
2092 
2093   if (strcasestr (name, ".HCD"))
2094     {
2095 
2096       // Enable Hu-Go! Cd Definition
2097       CD_emulation = 5;
2098 
2099       Log ("HCD emulation enabled\n");
2100 
2101       // Load correct ISO filename
2102       strcpy (ISO_filename, name);
2103 
2104       if (!fill_HCD_info (name))
2105 	return 1;
2106 
2107       LOAD_INTEGRATED_SYS_FILE;
2108 
2109     }
2110   else if (strcasestr (name, ".ISO"))
2111     {
2112 
2113       // Enable ISO support
2114       CD_emulation = 2;
2115 
2116       // Load correct ISO filename
2117       strcpy (ISO_filename, name);
2118 
2119       LOAD_INTEGRATED_SYS_FILE;
2120     }
2121   else if (strcasestr (name, ".ISQ"))
2122     {
2123 
2124       // Enable ISQ support
2125       CD_emulation = 3;
2126 
2127       // Load correct ISO filename
2128       strcpy (ISO_filename, name);
2129 
2130       LOAD_INTEGRATED_SYS_FILE;
2131     }
2132   else if (strcasestr (name, ".BIN"))
2133     {
2134 
2135       // Enable BIN support
2136       CD_emulation = 4;
2137 
2138       // Load correct ISO filename
2139       strcpy (ISO_filename, name);
2140 
2141       LOAD_INTEGRATED_SYS_FILE;
2142     }
2143   else if (strcasestr (name, ".ZIP"))
2144     {
2145 #ifdef MSDOS
2146       char tmp_char[128], tmp_char2[128], tmp_char3[128];
2147       char *array_arg[6] =
2148 	{ tmp_char3, tmp_char, "-Cjoqq", tmp_char2, "*.pce", NULL };
2149       sprintf (tmp_char, "%sHU-GO!.TMP/*.*", short_exe_name);
2150       for_each_file (tmp_char, 32, delete_file_tmp, 0);
2151 
2152       sprintf (tmp_char, "-d%sHU-GO!.TMP", short_exe_name);
2153       sprintf (tmp_char2, "%s", name);
2154       sprintf (tmp_char3, "%sHU-GO!.TMP/REDIR.RDF", short_exe_name);
2155 
2156       DecompressArchive (5, array_arg);
2157 
2158 
2159       if (!strcmp (name_to_extract, ""))
2160 	sprintf (tmp_path, "%sHU-GO!.TMP/%sPCE", short_exe_name,
2161 		 short_cart_name);
2162       else
2163 	sprintf (tmp_path, "%sHU-GO!.TMP/%s", short_exe_name,
2164 		 name_to_extract);
2165 #else
2166       char* filename_in_archive = NULL;
2167 
2168       Log("Testing archive %s\n", name);
2169       filename_in_archive = find_possible_filename_in_zip(name);
2170       Log("Return value = (%p) %s\n", filename_in_archive, filename_in_archive);
2171       if (strcmp(filename_in_archive,""))
2172         {
2173 	  char* unzipped_rom;
2174 	  size_t unzipped_rom_size;
2175 
2176           Log("Found %s in %s\n", filename_in_archive, name);
2177           unzipped_rom = extract_file_in_memory(name, filename_in_archive, &unzipped_rom_size);
2178 
2179 	  ROM_size = unzipped_rom_size / 0x2000;
2180 
2181 #if defined(SHARED_MEMORY)
2182 	  shm_rom_handle =
2183 	    shmget ((key_t) SHM_ROM_HANDLE, unzipped_rom_size,
2184 		    IPC_CREAT | IPC_EXCL | 0666);
2185 
2186 	  if (shm_rom_handle == -1)
2187 	    {
2188 	      fprintf (stderr, "Couldn't get shared memory (%d bytes)\n", fsize);
2189 	      return 1;
2190 	    }
2191 	  else
2192 	    {
2193 	      ROM = (char *) shmat (shm_rom_handle, NULL, 0);
2194 	      if (ROM == NULL)
2195 		{
2196 		  fprintf (stderr, "Couldn't attach shared memory\n");
2197 		  return 1;
2198 		}
2199 	      else
2200 		{
2201 		  /* Copy into the shared memory, by skipping an eventual header
2202 		   */
2203 		  memcpy(ROM,
2204 			 unzipped_rom + (unzipped_rom_size & 0x1FF),
2205 			 unzipped_rom_size & ~0x1FF);
2206 		  free(unzipped_rom);
2207 		}
2208 	    }
2209 #else
2210 	  if ((unzipped_rom_size & 0x1FFF) == 0)
2211 	    {
2212 	      /* No header */
2213 	      ROM = unzipped_rom;
2214 	    }
2215 	  else
2216 	    {
2217 	      ROM = malloc(unzipped_rom_size & ~0x1FFF);
2218 	      memcpy(ROM,
2219 		     unzipped_rom + (unzipped_rom_size & 0x1FFF),
2220 		     unzipped_rom_size & ~0x1FFF);
2221 	      free(unzipped_rom);
2222 	    }
2223 #endif
2224 	return 0;
2225         }
2226 #endif
2227 
2228       /*
2229       strcpy (true_file_name, tmp_path);
2230       fp = fopen (tmp_path, "rb");
2231       */
2232     }
2233   else
2234     {
2235 
2236       CD_emulation = 0;
2237       strcpy (true_file_name, name);
2238       fp = fopen (name, "rb");
2239     }
2240 
2241   if (fp == NULL)
2242     {
2243 
2244       if (!check_char (name, '.'))	//if dot omitted, we try with PCE extension
2245         {
2246           strcat (name, ".pce");
2247           return CartLoad (name);
2248         };
2249 
2250       if (strcasestr (name, ".pce"))	//if filename with .PCE doesn't exist, it may be in ZIP
2251         {
2252           strcpy (&name[strlen (name) - 4], ".zip");
2253           return CartLoad (name);
2254         };
2255 
2256       return -1;
2257     }
2258 
2259 	if (cart_name != name)
2260 	{	// Avoids warning when copying passing cart_name as parameter
2261 		#warning find where this weird call is done
2262   		strcpy (cart_name, name);
2263 	}
2264 
2265   // find file size
2266   fseek (fp, 0, SEEK_END);
2267   fsize = ftell (fp);
2268 
2269   // ajust var if header present
2270   fseek (fp, fsize & 0x1fff, SEEK_SET);
2271   fsize &= ~0x1fff;
2272 
2273   // read ROM
2274 #if defined(SHARED_MEMORY)
2275 	shm_rom_handle =
2276 		shmget ((key_t) SHM_ROM_HANDLE, fsize,
2277 			IPC_CREAT | IPC_EXCL | 0666);
2278 
2279 	if (shm_rom_handle == -1)
2280 		fprintf (stderr, "Couldn't get shared memory (%d bytes)\n", fsize);
2281 	else
2282 	{
2283 		ROM = (char *) shmat (shm_rom_handle, NULL, 0);
2284 		if (ROM == NULL)
2285 			fprintf (stderr, "Couldn't attach shared memory\n");
2286 	}
2287 
2288 #else
2289 	ROM = (UChar *) malloc (fsize);
2290 #endif
2291   ROM_size = fsize / 0x2000;
2292   fread (ROM, 1, fsize, fp);
2293 
2294   fclose (fp);
2295 
2296   return 0;
2297 }
2298 
2299 
2300 #ifndef KERNEL_DS
2301 int
ResetPCE(M6502 * M)2302 ResetPCE (M6502 * M)
2303 {
2304   int i;
2305 
2306   memset (M, 0, sizeof (*M));
2307   memset (SPRAM, 0, 64 * 8);
2308 
2309   TimerCount = TimerPeriod;
2310   M->IPeriod = IPeriod;
2311   M->TrapBadOps = 1;
2312   memset (&io, 0, sizeof (IO));
2313   scanline = 0;
2314   io.vdc_status = 0;
2315   io.vdc_inc = 1;
2316   io.minline = 0;
2317   io.maxline = 255;
2318   io.irq_mask = 0;
2319   io.psg_volume = 0;
2320   io.psg_ch = 0;
2321 
2322 /* TEST */
2323   io.screen_w = 255;
2324 /* TEST */// normally 256
2325 
2326 /* TEST */
2327 //   io.screen_h = 214;
2328 /* TEST */
2329 
2330 /* TEST */
2331 //      io.screen_h = 240;
2332 /* TEST */
2333 
2334   io.screen_h = 224;
2335 
2336   {
2337     UInt32 x, y = (WIDTH - io.screen_w) / 2 - 512 * WIDTH;
2338     for (x = 0; x < 1024; x++)
2339       {
2340 	spr_init_pos[x] = y;
2341 	y += WIDTH;
2342       }
2343     //pos = WIDTH*(HEIGHT-FC_H)/2+(WIDTH-FC_W)/2+WIDTH*y+x;
2344   }
2345 
2346   for (i = 0; i < 6; i++)
2347     {
2348       io.PSG[i][4] = 0x80;
2349     }
2350   CycleOld = 0;
2351   Reset6502 (M);
2352 
2353   if (debug_on_beginning)
2354     {
2355 
2356       Bp_list[GIVE_HAND_BP].position = M->PC.W;
2357 
2358       Bp_list[GIVE_HAND_BP].original_op = Op6502 (M->PC.W);
2359 
2360       Bp_list[GIVE_HAND_BP].flag = ENABLED;
2361 
2362       Wr6502 (M->PC.W, 0xB + 0x10 * GIVE_HAND_BP);
2363 
2364     }
2365 
2366   if (((CD_emulation >= 2) && (CD_emulation <= 5))
2367       && (!strcmp (ISO_filename, "")))
2368     CD_emulation = 0;		// if no ISO name given, give up the emulation
2369 
2370   if ((CD_emulation == 2) || (CD_emulation == 4))
2371     {
2372 
2373       if (!(iso_FILE = fopen (ISO_filename, "rb")))
2374 	{
2375 	  sprintf (exit_message, MESSAGE[language][iso_file_not_found],
2376 		   ISO_filename);
2377 	  return 1;
2378 	}
2379 
2380       fill_cd_info ();
2381 
2382     }
2383 /*
2384 ####################################
2385 ####################################
2386 ####################################
2387 ####################################
2388 2KILL :: BEGIN
2389 ####################################
2390 ####################################
2391 ####################################
2392 ####################################
2393 */
2394 #ifdef ALLEGRO
2395   else if (CD_emulation == 3)
2396     {
2397 
2398       if (!(packed_iso_FILE = pack_fopen (ISO_filename, F_READ_PACKED)))
2399 	{
2400 	  sprintf (exit_message, MESSAGE[language][iso_file_not_found],
2401 		   ISO_filename);
2402 	  return 1;
2403 	}
2404 
2405       packed_iso_filesize = 0;
2406       while (!pack_feof (packed_iso_FILE))
2407 	{
2408 	  pack_getc (packed_iso_FILE);
2409 	  packed_iso_filesize++;
2410 	}
2411 
2412       Log ("packed filesize is %d\n", packed_iso_filesize);
2413 
2414       pack_fclose (packed_iso_FILE);
2415       packed_iso_FILE = pack_fopen (ISO_filename, F_READ_PACKED);
2416 
2417       ISQ_position = 0;
2418 
2419     }
2420 #endif
2421 /*
2422 ####################################
2423 ####################################
2424 ####################################
2425 ####################################
2426 2KILL :: END
2427 ####################################
2428 ####################################
2429 ####################################
2430 ####################################
2431 */
2432 
2433   Log ("Cd_emulation is %d\n", CD_emulation);
2434 
2435   if (CD_emulation)
2436     {
2437       // We set illegal opcodes to handle CD Bios functions
2438       UInt16 x;
2439 
2440       Log ("Will hook cd functions\n");
2441 
2442       if (!minimum_bios_hooking)
2443 	for (x = 0x01; x < 0x4D; x++)
2444 	  if (x != 0x22)	// the 0x22th jump is special, points to a one byte routine
2445 	    {
2446 	      UInt16 dest;
2447 	      dest = Op6502 (0xE000 + x * 3 + 1);
2448 	      dest += 256 * Op6502 (0xE000 + x * 3 + 2);
2449 
2450 	      CDBIOS_replace[x][0] = Op6502 (dest);
2451 	      CDBIOS_replace[x][1] = Op6502 (dest + 1);
2452 
2453 	      Wr6502 (dest, 0xFC);
2454 	      Wr6502 (dest + 1, x);
2455 
2456 	    }
2457 
2458     }
2459   return 0;
2460 }
2461 #else
2462 int
ResetPCE()2463 ResetPCE ()
2464 {
2465   int i;
2466 
2467   memset (SPRAM, 0, 64 * 8);
2468 
2469   TimerCount = TimerPeriod;
2470   memset (&io, 0, sizeof (IO));
2471   scanline = 0;
2472   io.vdc_status = 0;
2473   io.vdc_inc = 1;
2474   io.minline = 0;
2475   io.maxline = 255;
2476   io.irq_mask = 0;
2477   io.psg_volume = 0;
2478   io.psg_ch = 0;
2479 
2480   zp_base = RAM;
2481   sp_base = RAM + 0x100;
2482 
2483 /* TEST */
2484   io.screen_w = 255;
2485 /* TEST */// normally 256
2486 
2487 /* TEST */
2488 //   io.screen_h = 214;
2489 /* TEST */
2490 
2491 /* TEST */
2492 //      io.screen_h = 240;
2493 /* TEST */
2494 
2495   io.screen_h = 224;
2496 
2497   {
2498     UInt32 x, y = (WIDTH - io.screen_w) / 2 - 512 * WIDTH;
2499     for (x = 0; x < 1024; x++)
2500       {
2501 	spr_init_pos[x] = y;
2502 	y += WIDTH;
2503       }
2504     //pos = WIDTH*(HEIGHT-FC_H)/2+(WIDTH-FC_W)/2+WIDTH*y+x;
2505   }
2506 
2507   for (i = 0; i < 6; i++)
2508     {
2509       io.PSG[i][4] = 0x80;
2510     }
2511   CycleOld = 0;
2512 
2513 #if !defined(TEST_ROM_RELOCATED)
2514   mmr[7] = 0x00;
2515   bank_set (7, 0x00);
2516 
2517   mmr[6] = 0x05;
2518   bank_set (6, 0x05);
2519 
2520   mmr[5] = 0x04;
2521   bank_set (5, 0x04);
2522 
2523   mmr[4] = 0x03;
2524   bank_set (4, 0x03);
2525 
2526   mmr[3] = 0x02;
2527   bank_set (3, 0x02);
2528 
2529   mmr[2] = 0x01;
2530   bank_set (2, 0x01);
2531 
2532 #else
2533   mmr[7] = 0x68;
2534   bank_set (7, 0x68);
2535 
2536   mmr[6] = 0x05;
2537   bank_set (6, 0x05 + 0x68);
2538 
2539   mmr[5] = 0x04;
2540   bank_set (5, 0x04 + 0x68);
2541 
2542   mmr[4] = 0x03;
2543   bank_set (4, 0x03 + 0x68);
2544 
2545   mmr[3] = 0x02;
2546   bank_set (3, 0x02 + 0x68);
2547 
2548   mmr[2] = 0x01;
2549   bank_set (2, 0x01 + 0x68);
2550 
2551 #endif
2552 
2553   mmr[1] = 0xF8;
2554   bank_set (1, 0xF8);
2555 
2556   mmr[0] = 0xFF;
2557   bank_set (0, 0xFF);
2558 
2559   reg_a = reg_x = reg_y = 0x00;
2560   reg_p = FL_TIQ;
2561 
2562   reg_s = 0xFF;
2563 
2564   reg_pc = Op6502 (VEC_RESET) + 256 * Op6502 (VEC_RESET + 1);
2565 
2566   CycleNew = 0;
2567 
2568   if (debug_on_beginning)
2569     {
2570 
2571       Bp_list[GIVE_HAND_BP].position = reg_pc;
2572 
2573       Bp_list[GIVE_HAND_BP].original_op = Op6502 (reg_pc);
2574 
2575       Bp_list[GIVE_HAND_BP].flag = ENABLED;
2576 
2577       Wr6502 (
2578 				reg_pc,
2579 				0xB + 0x10 * GIVE_HAND_BP
2580 			);
2581 
2582     }
2583 
2584   if (((CD_emulation >= 2) && (CD_emulation <= 5))
2585       && (!strcmp (ISO_filename, "")))
2586     CD_emulation = 0;		// if no ISO name given, give up the emulation
2587 
2588   if ((CD_emulation == 2) || (CD_emulation == 4))
2589     {
2590 
2591       if (!(iso_FILE = fopen (ISO_filename, "rb")))
2592 	{
2593 	  sprintf (exit_message, MESSAGE[language][iso_file_not_found],
2594 		   ISO_filename);
2595 	  return 1;
2596 	}
2597 
2598       fill_cd_info ();
2599 
2600     }
2601 /*
2602 ####################################
2603 ####################################
2604 ####################################
2605 ####################################
2606 2KILL :: END
2607 ####################################
2608 ####################################
2609 ####################################
2610 ####################################
2611 */
2612 #ifdef ALLEGRO
2613   else if (CD_emulation == 3)
2614     {
2615 
2616       if (!(packed_iso_FILE = pack_fopen (ISO_filename, F_READ_PACKED)))
2617 	{
2618 	  sprintf (exit_message, MESSAGE[language][iso_file_not_found],
2619 		   ISO_filename);
2620 	  return 1;
2621 	}
2622 
2623       packed_iso_filesize = 0;
2624       while (!pack_feof (packed_iso_FILE))
2625 	{
2626 	  pack_getc (packed_iso_FILE);
2627 	  packed_iso_filesize++;
2628 	}
2629 
2630       Log ("packed filesize is %d\n", packed_iso_filesize);
2631 
2632       pack_fclose (packed_iso_FILE);
2633       packed_iso_FILE = pack_fopen (ISO_filename, F_READ_PACKED);
2634 
2635       ISQ_position = 0;
2636 
2637     }
2638 #endif
2639 /*
2640 ####################################
2641 ####################################
2642 ####################################
2643 ####################################
2644 2KILL :: END
2645 ####################################
2646 ####################################
2647 ####################################
2648 ####################################
2649 */
2650 
2651   Log ("Cd_emulation is %d\n", CD_emulation);
2652 
2653   if (CD_emulation)
2654     {
2655       // We set illegal opcodes to handle CD Bios functions
2656       UInt16 x;
2657 
2658       Log ("Will hook cd functions\n");
2659 /* TODO : reenable minimum_bios_hooking when bios hooking rewritten */
2660 
2661       if (!minimum_bios_hooking)
2662 	for (x = 0x01; x < 0x4D; x++)
2663 	  if (x != 0x22)	// the 0x22th jump is special, points to a one byte routine
2664 	    {
2665 	      UInt16 dest;
2666 	      dest = Op6502 (0xE000 + x * 3 + 1);
2667 	      dest += 256 * Op6502 (0xE000 + x * 3 + 2);
2668 
2669 	      CDBIOS_replace[x][0] = Op6502 (dest);
2670 	      CDBIOS_replace[x][1] = Op6502 (dest + 1);
2671 
2672 	      Wr6502 (dest, 0xFC);
2673 	      Wr6502 (dest + 1, x);
2674 
2675 	    }
2676 
2677     }
2678   return 0;
2679 }
2680 #endif
2681 
2682 
2683 int
InitPCE(char * name,char * backmemname)2684 InitPCE (char *name, char *backmemname)
2685 {
2686   int i = 0, ROMmask;
2687   unsigned long CRC;
2688   int dummy;
2689   char *tmp_dummy;
2690   char local_us_encoded_card = 0;
2691 
2692   if ((!strcmp (name, "")) && (CD_emulation != 1))
2693     return -1;
2694 
2695   if (CartLoad (name))
2696     return -1;
2697 
2698 	osd_fix_filename_slashes(cart_name);
2699 
2700   if (!(tmp_dummy = (char *) (strrchr (cart_name, '/'))))
2701     tmp_dummy = &cart_name[0];
2702   else
2703     tmp_dummy++;
2704 
2705   memset (short_cart_name, 0, 80);
2706   while ((tmp_dummy[i]) && (tmp_dummy[i] != '.')) {
2707     short_cart_name[i] = tmp_dummy[i];
2708     i++;
2709   }
2710 
2711   if (strlen (short_cart_name))
2712     if (short_cart_name[strlen (short_cart_name) - 1] != '.')
2713       {
2714 	short_cart_name[strlen (short_cart_name) + 1] = 0;
2715 	short_cart_name[strlen (short_cart_name)] = '.';
2716       }
2717 
2718 	osd_fix_filename_slashes(ISO_filename);
2719 
2720   if (!(tmp_dummy = (char *) (strrchr (ISO_filename, '\\'))))
2721     tmp_dummy = &ISO_filename[0];
2722   else
2723     tmp_dummy++;
2724 
2725 
2726   memset (short_iso_name, 0, 80);
2727   i = 0;
2728   while ((tmp_dummy[i]) && (tmp_dummy[i] != '.')) {
2729     short_iso_name[i] = tmp_dummy[i];
2730     i++;
2731   }
2732 
2733   if (strlen (short_iso_name))
2734     if (short_iso_name[strlen (short_iso_name) - 1] != '.')
2735       {
2736         short_iso_name[strlen (short_iso_name) + 1] = 0;
2737         short_iso_name[strlen (short_iso_name)] = '.';
2738       }
2739 
2740 #ifdef WIN32
2741 
2742   switch (CD_emulation)
2743     {
2744     case 0:
2745       sprintf (sav_path, "%s%ssav", sav_basepath, short_cart_name);
2746       break;
2747     case 1:
2748       sprintf (sav_path, "%scd_sav", sav_basepath);
2749       break;
2750     case 2:
2751     case 3:
2752     case 4:
2753     case 5:
2754       sprintf (sav_path, "%s%ssvi", sav_basepath, short_iso_name);
2755       break;
2756     }
2757 
2758   Log ("Saved path is %s\n", sav_path);
2759 
2760 #else
2761 
2762   {
2763     char home_directory[256];
2764 
2765     strcpy (home_directory, getenv ("HOME"));
2766 
2767     switch (CD_emulation)
2768       {
2769       case 0:
2770 	sprintf (sav_path, "%s/.hugo/%ssav", home_directory, short_cart_name);
2771 	break;
2772       case 1:
2773 	sprintf (sav_path, "%s/.hugo/cd_sav", short_exe_name);
2774 	break;
2775       case 2:
2776       case 3:
2777       case 4:
2778       case 5:
2779 	sprintf (sav_path, "%s/.hugo/%ssvi", short_exe_name, short_iso_name);
2780 	break;
2781       }
2782 
2783     Log ("Saved path is %s\n", sav_path);
2784 
2785   }
2786 
2787 #endif
2788 
2789   // Set the base frequency
2790   BaseClock = 7800000;
2791 
2792   // Set the interruption period
2793   IPeriod = BaseClock / (scanlines_per_frame * 60);
2794 
2795   hard_init();
2796 
2797   pce_build_romlist();
2798 
2799   /* TEST */
2800   io.screen_h = 224;
2801   /* TEST */
2802   io.screen_w = 256;
2803 
2804   if (!builtin_system_used)
2805     {
2806 
2807       CRC = CRC_file (true_file_name);
2808       /* I'm doing it only here 'coz cartload set
2809          true_file_name    */
2810 
2811       NO_ROM = 0xFFFF;
2812 
2813       for (dummy = 0; dummy < pce_romlist_size; dummy++)
2814 	if (CRC == pce_romlist[dummy].CRC)
2815 	  NO_ROM = dummy;
2816     }
2817   else
2818     {
2819       NO_ROM = 255;
2820       printf("ROM not in database: CRC=%lx\n", CRC);
2821     }
2822 
2823   memset (WRAM, 0, 0x2000);
2824   WRAM[0] = 0x48;		/* 'H' */
2825   WRAM[1] = 0x55;		/* 'U' */
2826   WRAM[2] = 0x42;		/* 'B' */
2827   WRAM[3] = 0x4D;		/* 'M' */
2828   WRAM[5] = 0xA0;		/* WRAM[4-5] = 0xA000, end of free mem ? */
2829   WRAM[6] = 0x10;		/* WRAM[6-7] = 0x8010, beginning of free mem ? */
2830   WRAM[7] = 0x80;
2831 
2832   memset (VRAM, 0, VRAMSIZE);
2833 
2834   memset (VRAM2, 0, VRAMSIZE);
2835 
2836   memset (VRAMS, 0, VRAMSIZE);
2837 
2838   IOAREA = (UChar *) malloc (0x2000);
2839   memset (IOAREA, 0xFF, 0x2000);
2840 
2841   memset (vchange, 1, VRAMSIZE / 32);
2842 
2843   memset (vchanges, 1, VRAMSIZE / 128);
2844 
2845 #ifndef FINAL_RELEASE
2846   if (NO_ROM != 0xFFFF)
2847     fprintf (stderr, "flags = %x\n", (pce_romlist + NO_ROM) ? pce_romlist[NO_ROM].flags : 0);
2848 #endif
2849 
2850 	local_us_encoded_card = US_encoded_card;
2851 
2852    if ((NO_ROM != 0xFFFF) && (pce_romlist + NO_ROM) && (pce_romlist[NO_ROM].flags & US_ENCODED))
2853     local_us_encoded_card = 1;
2854 
2855    if (ROM[0x1FFF] < 0xE0)
2856    {
2857 	   Log("This rom is probably US encrypted, decrypting ..\n");
2858 #if !defined(FINAL_RELEASE)
2859 	   fprintf(stderr, "This rom is probably US encrypted, decrypting ..\n");
2860 #endif
2861 		local_us_encoded_card = 1;
2862    }
2863 
2864   if (local_us_encoded_card)
2865     {
2866       UInt32 x;
2867       UChar inverted_nibble[16] = { 0, 8, 4, 12,
2868 	2, 10, 6, 14,
2869 	1, 9, 5, 13,
2870 	3, 11, 7, 15
2871       };
2872 
2873       for (x = 0; x < ROM_size * 0x2000; x++)
2874 	{
2875 	  UChar temp;
2876 
2877 	  temp = ROM[x] & 15;
2878 
2879 	  ROM[x] &= ~0x0F;
2880 	  ROM[x] |= inverted_nibble[ROM[x] >> 4];
2881 
2882 	  ROM[x] &= ~0xF0;
2883 	  ROM[x] |= inverted_nibble[temp] << 4;
2884 
2885 	}
2886     }
2887 /*
2888   if (CD_emulation)
2889     {
2890 
2891       cd_extra_mem = (UChar *) malloc (0x10000);
2892       memset (cd_extra_mem, 0, 0x10000);
2893 
2894       cd_extra_super_mem = (UChar *) malloc (0x30000);
2895       memset (cd_extra_super_mem, 0, 0x30000);
2896 
2897       ac_extra_mem = (UChar *) malloc (0x200000);
2898       memset (ac_extra_mem, 0, 0x200000);
2899 
2900       cd_sector_buffer = (UChar *) malloc (0x2000);
2901 
2902       // cd_read_buffer = (UChar *)malloc(0x2000);
2903 
2904     }
2905 */
2906 
2907 /*
2908 ####################################
2909 ####################################
2910 ####################################
2911 ####################################
2912 2KILL :: BEGIN
2913 ####################################
2914 ####################################
2915 ####################################
2916 ####################################
2917 */
2918 #ifdef ALLEGRO
2919 
2920   if ((NO_ROM != 0xFFFF) && (pce_romlist + NO_ROM) && (pce_romlist[NO_ROM].flags & PINBALL_KEY))
2921 
2922     for (dummy = 0; dummy < 5; dummy++)
2923       {
2924 	config[current_config].joy_mapping[dummy][J_II] = KEY_RSHIFT;
2925 	config[current_config].joy_mapping[dummy][J_LEFT] = KEY_LSHIFT;
2926 	config[current_config].joy_mapping[dummy][J_I] = KEY_STOP;
2927 	config[current_config].joy_mapping[dummy][J_RIGHT] = KEY_Z;
2928       }
2929 
2930 #endif
2931 /*
2932 ####################################
2933 ####################################
2934 ####################################
2935 ####################################
2936 2KILL :: END
2937 ####################################
2938 ####################################
2939 ####################################
2940 ####################################
2941 */
2942 
2943   if ((NO_ROM != 0xFFFF) && (pce_romlist + NO_ROM) && (pce_romlist[NO_ROM].flags & TWO_PART_ROM))
2944     ROM_size = 0x30;
2945   // Used for example with Devil Crush 512Ko
2946 
2947   ROMmask = 1;
2948   while (ROMmask < ROM_size)
2949     ROMmask <<= 1;
2950   ROMmask--;
2951 
2952 #ifndef FINAL_RELEASE
2953   fprintf (stderr, "ROMmask=%02X, ROM_size=%02X\n", ROMmask, ROM_size);
2954 #endif
2955 
2956 	for (i = 0; i < 0xFF; i++)
2957 		{
2958 			ROMMapR[i] = trap_ram_read;
2959 			ROMMapW[i] = trap_ram_write;
2960 		}
2961 
2962 #if ! defined(TEST_ROM_RELOCATED)
2963   for (i = 0; i < 0x80; i++)
2964     {
2965       if (ROM_size == 0x30)
2966 				{
2967 					switch (i & 0x70)
2968 						{
2969 							case 0x00:
2970 							case 0x10:
2971 							case 0x50:
2972 								ROMMapR[i] = ROM + (i & ROMmask) * 0x2000;
2973 								break;
2974 							case 0x20:
2975 							case 0x60:
2976 							  ROMMapR[i] = ROM + ((i - 0x20) & ROMmask) * 0x2000;
2977 								break;
2978 							case 0x30:
2979 							case 0x70:
2980 							  ROMMapR[i] = ROM + ((i - 0x10) & ROMmask) * 0x2000;
2981 								break;
2982 							case 0x40:
2983 							  ROMMapR[i] = ROM + ((i - 0x20) & ROMmask) * 0x2000;
2984 								break;
2985 						}
2986 				}
2987       else
2988 				ROMMapR[i] = ROM + (i & ROMmask) * 0x2000;
2989     }
2990 #else
2991   for (i = 0x68; i < 0x88; i++)
2992     {
2993       if (ROM_size == 0x30)
2994 				{
2995 					switch (i & 0x70)
2996 						{
2997 							case 0x00:
2998 							case 0x10:
2999 							case 0x50:
3000 								ROMMapR[i] = ROM + ((i - 0x68) & ROMmask) * 0x2000;
3001 								ROMMapW[i] = ROM + ((i - 0x68) & ROMmask) * 0x2000;
3002 								break;
3003 							case 0x20:
3004 							case 0x60:
3005 								ROMMapR[i] = ROM + (((i - 0x68) - 0x20) & ROMmask) * 0x2000;
3006 								ROMMapW[i] = ROM + (((i - 0x68) - 0x20) & ROMmask) * 0x2000;
3007 								break;
3008 							case 0x30:
3009 							case 0x70:
3010 								ROMMapR[i] = ROM + (((i - 0x68) - 0x10) & ROMmask) * 0x2000;
3011 								ROMMapW[i] = ROM + (((i - 0x68) - 0x10) & ROMmask) * 0x2000;
3012 								break;
3013 							case 0x40:
3014 								ROMMapR[i] = ROM + (((i - 0x68) - 0x20) & ROMmask) * 0x2000;
3015 								ROMMapW[i] = ROM + (((i - 0x68) - 0x20) & ROMmask) * 0x2000;
3016 								break;
3017 						}
3018 				}
3019       else
3020 				{
3021 					ROMMapR[i] = ROM + ((i - 0x68) & ROMmask) * 0x2000;
3022 					ROMMapW[i] = ROM + ((i - 0x68) & ROMmask) * 0x2000;
3023 				}
3024     }
3025 #endif
3026 
3027   if (NO_ROM != 0xFFFF)
3028     {
3029 #ifndef FINAL_RELEASE
3030       fprintf (stderr, "ROM NAME : %s\n", (pce_romlist + NO_ROM) ? pce_romlist[NO_ROM].name : "Unknown");
3031 #endif
3032       osd_gfx_set_message((pce_romlist + NO_ROM) ? pce_romlist[NO_ROM].name : "Unknown");
3033       message_delay = 60 * 5;
3034     }
3035   else
3036     {
3037       osd_gfx_set_message (MESSAGE[language][unknown_rom]);
3038       message_delay = 60 * 5;
3039     }
3040 
3041   if ((NO_ROM != 0xFFFF) && (pce_romlist + NO_ROM) && (pce_romlist[NO_ROM].flags & POPULOUS))
3042     {
3043       populus = TRUE;
3044 #ifndef FINAL_RELEASE
3045       fprintf (stderr, "POPULOUS DETECTED!!!\n");
3046 #endif
3047       if (!(PopRAM = (UChar *) malloc (PopRAMsize)))
3048 				perror (MESSAGE[language][no_mem]);
3049 
3050       ROMMapW[0x40] = PopRAM;
3051       ROMMapW[0x41] = PopRAM + 0x2000;
3052       ROMMapW[0x42] = PopRAM + 0x4000;
3053       ROMMapW[0x43] = PopRAM + 0x6000;
3054 
3055       ROMMapR[0x40] = PopRAM;
3056       ROMMapR[0x41] = PopRAM + 0x2000;
3057       ROMMapR[0x42] = PopRAM + 0x4000;
3058       ROMMapR[0x43] = PopRAM + 0x6000;
3059 
3060     }
3061   else
3062     {
3063       populus = FALSE;
3064       PopRAM = NULL;
3065     }
3066 
3067   if (CD_emulation)
3068     {
3069 
3070       ROMMapR[0x80] = cd_extra_mem;
3071       ROMMapR[0x81] = cd_extra_mem + 0x2000;
3072       ROMMapR[0x82] = cd_extra_mem + 0x4000;
3073       ROMMapR[0x83] = cd_extra_mem + 0x6000;
3074       ROMMapR[0x84] = cd_extra_mem + 0x8000;
3075       ROMMapR[0x85] = cd_extra_mem + 0xA000;
3076       ROMMapR[0x86] = cd_extra_mem + 0xC000;
3077       ROMMapR[0x87] = cd_extra_mem + 0xE000;
3078 
3079       ROMMapW[0x80] = cd_extra_mem;
3080       ROMMapW[0x81] = cd_extra_mem + 0x2000;
3081       ROMMapW[0x82] = cd_extra_mem + 0x4000;
3082       ROMMapW[0x83] = cd_extra_mem + 0x6000;
3083       ROMMapW[0x84] = cd_extra_mem + 0x8000;
3084       ROMMapW[0x85] = cd_extra_mem + 0xA000;
3085       ROMMapW[0x86] = cd_extra_mem + 0xC000;
3086       ROMMapW[0x87] = cd_extra_mem + 0xE000;
3087 
3088       for (i = 0x68; i < 0x80; i++)
3089 				{
3090 					ROMMapR[i] = cd_extra_super_mem + 0x2000 * (i - 0x68);
3091 					ROMMapW[i] = cd_extra_super_mem + 0x2000 * (i - 0x68);
3092 				}
3093 
3094     }
3095 
3096   ROMMapR[0xF7] = WRAM;
3097   ROMMapW[0xF7] = WRAM;
3098 
3099   ROMMapR[0xF8] = RAM;
3100 	ROMMapW[0xF8] = RAM;
3101 
3102 	if (option.want_supergraphx_emulation)
3103 		{
3104 			ROMMapW[0xF9] = RAM + 0x2000;
3105 			ROMMapW[0xFA] = RAM + 0x4000;
3106 			ROMMapW[0xFB] = RAM + 0x6000;
3107 
3108 			ROMMapR[0xF9] = RAM + 0x2000;
3109 			ROMMapR[0xFA] = RAM + 0x4000;
3110 			ROMMapR[0xFB] = RAM + 0x6000;
3111 		}
3112 
3113 	/*
3114 	#warning REMOVE ME
3115 	// ROMMapR[0xFC] = RAM + 0x6000;
3116 	ROMMapW[0xFC] = NULL;
3117 	*/
3118 
3119   ROMMapR[0xFF] = IOAREA;
3120 	ROMMapW[0xFF] = IOAREA;
3121 
3122   {
3123     FILE *fp;
3124     fp = fopen (backmemname, "rb");
3125 
3126     if (fp == NULL)
3127       fprintf (stderr, "Can't open %s\n", backmemname);
3128     else
3129       {
3130 	fread (WRAM, 0x2000, 1, fp);
3131 	fclose (fp);
3132       }
3133 
3134   }
3135 
3136   if ((NO_ROM != 0xFFFF) && (pce_romlist + NO_ROM) && (pce_romlist[NO_ROM].flags & CD_SYSTEM))
3137     {
3138       UInt16 offset;
3139       UChar new_val;
3140 
3141       offset = atoi (pce_romlist[NO_ROM].note);
3142       new_val = atoi (&pce_romlist[NO_ROM].note[6]);
3143 
3144       if (offset)
3145 				ROMMapW[0xE1][offset & 0x1fff] = new_val;
3146 
3147     }
3148 
3149   return 0;
3150 }
3151 
3152 
3153 #ifndef KERNEL_DS
3154 int
RunPCE(void)3155 RunPCE (void)
3156 {
3157   if (!ResetPCE (&M))
3158     Run6502 ();
3159   return 1;
3160 }
3161 #else
3162 int
RunPCE(void)3163 RunPCE (void)
3164 {
3165   if (!ResetPCE ())
3166     exe_go ();
3167   return 1;
3168 }
3169 #endif
3170 
3171 void
TrashPCE(char * backmemname)3172 TrashPCE (char *backmemname)
3173 {
3174   FILE *fp;
3175   char *tmp_buf = (char *) alloca (256);
3176 
3177   // Save the backup ram into file
3178   if (!(fp = fopen (backmemname, "wb")))
3179     {
3180       memset (WRAM, 0, 0x2000);
3181       Log ("Can't open %s for saving RAM\n", backmemname);
3182     }
3183   else
3184     {
3185       fwrite (WRAM, 0x2000, 1, fp);
3186       fclose (fp);
3187       Log ("%s used for saving RAM\n", backmemname);
3188     }
3189 
3190   // Set volume to zero
3191   io.psg_volume = 0;
3192 
3193 #if defined(ALLEGRO)
3194   sprintf (tmp_buf, "%s/HU-GO!.TMP/*.*", short_exe_name);
3195   for_each_file (tmp_buf, 32, delete_file_tmp, 0);
3196 #elif defined(LINUX)
3197 		sprintf (tmp_buf, "rm -rf %s/HU-GO!.TMP/*", short_exe_name);
3198 	    system(tmp_buf);
3199 #endif
3200   sprintf (tmp_buf, "%s/HU-GO!.TMP", short_exe_name);
3201   rmdir (tmp_buf);
3202 
3203   if (CD_emulation == 1)
3204     osd_cd_close ();
3205 
3206   if ((CD_emulation == 2) || (CD_emulation == 4))
3207     fclose (iso_FILE);
3208 
3209 /*
3210 ####################################
3211 ####################################
3212 ####################################
3213 ####################################
3214 2KILL :: BEGIN
3215 ####################################
3216 ####################################
3217 ####################################
3218 ####################################
3219 */
3220 #ifdef ALLEGRO
3221   if (CD_emulation == 3)
3222     pack_fclose (packed_iso_FILE);
3223 #endif
3224 /*
3225 ####################################
3226 ####################################
3227 ####################################
3228 ####################################
3229 2KILL :: END
3230 ####################################
3231 ####################################
3232 ####################################
3233 ####################################
3234 */
3235 
3236   if (CD_emulation == 5)
3237     HCD_shutdown ();
3238 
3239   if (IOAREA)
3240     free (IOAREA);
3241   if (ROM)
3242 		{
3243 #if defined(SHARED_MEMORY)
3244 	if (shmctl (shm_rom_handle, IPC_RMID, NULL) == -1)
3245 		fprintf (stderr, "Couldn't destroy shared memory\n");
3246 #else
3247 			free(ROM);
3248 #endif
3249 		}
3250   if (PopRAM)
3251     free (PopRAM);
3252 /*
3253   if (CD_emulation)
3254     {
3255 
3256       if (cd_extra_mem)
3257 	free (cd_extra_mem);
3258       if (cd_sector_buffer)
3259 	free (cd_sector_buffer);
3260       if (cd_extra_super_mem)
3261 	free (cd_extra_super_mem);
3262       if (cd_buf)
3263 	free (cd_buf);
3264 
3265     }
3266 */
3267   hard_term();
3268 
3269   return;
3270 };
3271 
3272 #ifdef CHRONO
3273 unsigned nb_used[256], time_used[256];
3274 #endif
3275 
3276 #ifndef FINAL_RELEASE
3277 extern int mseq (unsigned *);
3278 extern void mseq_end ();
3279 extern void WriteBuffer_end ();
3280 extern void write_psg_end ();
3281 extern void WriteBuffer (char *, int, unsigned);
3282 #endif
3283 
3284 FILE *out_snd;
3285 
3286 #ifdef OLD_MAIN
3287 
3288 int
main(int argc,char * argv[])3289 main (int argc, char *argv[])
3290 {
3291   char backup_mem[80];
3292   char _BACKUP_DAT[] = "BACKUP.DAT";
3293   // Default name if none given
3294 
3295   char i, tmp_path[80];
3296 
3297 #ifdef CHRONO
3298   unsigned timax = 0, inst_max = 0;
3299 
3300   for (vmode = 0; vmode < 256; vmode++)
3301     time_used[vmode] = nb_used[vmode] = 0;
3302 
3303 #endif
3304 
3305 #ifdef LINUX
3306   {
3307     char* home_path;
3308 
3309     home_path = getenv("HOME");
3310 
3311     if (home_path)
3312       {
3313         sprintf(short_exe_name,"%s/.hugo/",home_path);
3314         mkdir(short_exe_name,0777);
3315         sprintf(log_filename,"%s%s",short_exe_name,LOG_NAME);
3316       }
3317     else
3318       {
3319         strcpy(short_exe_name,"./");
3320         strcpy(home_path,LOG_NAME);
3321       }
3322   }
3323 #endif
3324 
3325 #ifdef WIN32
3326   strcpy(log_filename,"c:\\hugo.log");
3327 #endif
3328 
3329 #ifdef MSDOS
3330   _crt0_startup_flags |= _CRT0_FLAG_NO_LFN;
3331   // Disable long filename to avoid mem waste in select_rom func.
3332 #endif
3333 
3334   init_log_file ();
3335 
3336   srand (time (NULL));
3337 
3338   parse_INIfile ();
3339 
3340 #warning check if ALLEGRO is ok with initializing the machine here
3341 
3342   if (!osd_init_machine ())
3343     return -1;
3344 
3345 #ifndef LINUX
3346 
3347   //  get_executable_name (short_exe_name, 256);
3348   strncpy(short_exe_name,argv[0],PATH_MAX);
3349   for (i = 0; short_exe_name[i]; i++)
3350     if (short_exe_name[i] == '\\')
3351       short_exe_name[i] = '/';
3352 
3353   if (strrchr (short_exe_name, '/'))
3354     *(char *) (strrchr (short_exe_name, '/') + 1) = 0;
3355   // add a trailing slash
3356 
3357 #else
3358 
3359   strcpy (short_exe_name, "./");
3360 
3361 #endif
3362 
3363 /*
3364 ####################################
3365 ####################################
3366 ####################################
3367 ####################################
3368 2KILL :: BEGIN
3369 ####################################
3370 ####################################
3371 ####################################
3372 ####################################
3373 */
3374 #if defined(EXTERNAL_DAT) && defined(ALLEGRO)
3375 
3376 #ifndef LINUX
3377   strcpy (tmp_path, short_exe_name);
3378   strcat (tmp_path, "HU-GO!.DAT");
3379 #else
3380   strcpy (tmp_path, "/etc/hugo.dat");
3381 #endif
3382   printf (" � Decrunching data file...");
3383   if (!(datafile = load_datafile (tmp_path)))
3384     {
3385       printf ("\n � ERROR!!\n � Datafile %s not found\n", tmp_path);
3386       exit (-1);
3387     }
3388 
3389 #endif
3390 /*
3391 ####################################
3392 ####################################
3393 ####################################
3394 ####################################
3395 2KILL :: END
3396 ####################################
3397 ####################################
3398 ####################################
3399 ####################################
3400 */
3401 
3402   strcpy (tmp_path, short_exe_name);
3403   strcat (tmp_path, "HU-GO!.TMP");
3404 
3405 #ifndef WIN32
3406   mkdir (tmp_path, 0);
3407 #else
3408   mkdir (tmp_path);
3409 #endif
3410 
3411 #ifdef ALLEGRO
3412 
3413 #if defined(MSDOS) || defined(WIN32)
3414 
3415   set_gfx_mode (GFX_AUTODETECT, 320, 200, 0, 0);
3416 
3417 #elif defined(LINUX)
3418 
3419 #if defined(ALLEGRO)
3420   if (set_gfx_mode (GFX_SAFE, 320, 200, 0, 0))
3421     {
3422       printf ("Error setting mode!\n");
3423       getchar ();
3424       exit (-2);
3425     }
3426 
3427 #endif // ALLEGRO
3428 
3429 #endif
3430 
3431 #endif // ALLEGRO
3432 
3433 /*
3434 ####################################
3435 ####################################
3436 ####################################
3437 ####################################
3438 2KILL :: BEGIN
3439 ####################################
3440 ####################################
3441 ####################################
3442 ####################################
3443 */
3444 #ifdef ALLEGRO
3445 
3446 #if defined(EXTERNAL_DAT)
3447 
3448   set_palette (datafile[INTRO_PAL].dat);
3449 
3450 
3451   /*
3452      (*fade_in_proc[rand () % nb_fadein]) (datafile[INTRO_PICTURE].dat, 0, 0,
3453      320, 200);
3454    */
3455   // Now the logo is displayed, let's be useful instead of wait
3456 
3457 #else
3458 
3459   fixup_datafile (data);
3460 
3461   set_palette (data[INTRO_PAL].dat);
3462 
3463 # ifndef LINUX
3464 
3465   (*fade_in_proc[rand () % nb_fadein]) (data[INTRO_PICTURE].dat, 0, 0, 320,
3466 					200);
3467   // Now the logo is displayed, let's be useful instead of waiting
3468 
3469 #else
3470 
3471   // blit(data[INTRO_PICTURE].dat, screen, 0, 0, 0, 0, 320, 200);
3472   {
3473 
3474     PALETTE dum_pal;
3475     BITMAP *dum = load_bitmap ("./hugo3.bmp", dum_pal);
3476     (*fade_in_proc[rand () % nb_fadein]) (dum, 0, 0, 320, 200);
3477     destroy_bitmap (dum);
3478 
3479   }
3480 #endif
3481 #endif
3482 #endif
3483 /*
3484 ####################################
3485 ####################################
3486 ####################################
3487 ####################################
3488 2KILL :: END
3489 ####################################
3490 ####################################
3491 ####################################
3492 ####################################
3493 */
3494 
3495   parse_commandline (argc, argv);
3496 
3497   if (!bmdefault)
3498     bmdefault = _BACKUP_DAT;
3499 
3500   strcpy (backup_mem, short_exe_name);
3501   strcat (backup_mem, bmdefault);
3502 
3503 #ifndef LINUX
3504   sprintf (sav_path, "%sSAV/", short_exe_name);
3505   sprintf (video_path, "%sVIDEO/", short_exe_name);
3506 #else
3507   {
3508     char tmp_home[256];
3509     strcpy (tmp_home, getenv ("HOME"));
3510 
3511     sprintf (sav_path, "%s/.hugo", tmp_home);
3512   }
3513 #endif
3514 
3515 /*
3516 ####################################
3517 ####################################
3518 ####################################
3519 ####################################
3520 2KILL :: BEGIN
3521 ####################################
3522 ####################################
3523 ####################################
3524 ####################################
3525 */
3526   /* TODO: make this allegro independant */
3527 #ifdef ALLEGRO
3528   if (!file_exists (sav_path, FA_DIREC, 0))
3529 #ifndef WIN32
3530     mkdir (sav_path, 0);
3531 #else
3532     mkdir (sav_path);
3533 #endif
3534   // Create a place for saved games if not exist
3535 #endif
3536 
3537   /* TODO: make this allegro independant */
3538 #ifdef ALLEGRO
3539   if (!file_exists (video_path, FA_DIREC, 0))
3540 #ifndef WIN32
3541     mkdir (video_path, 0);
3542 #else
3543     mkdir (video_path);
3544 #endif
3545   // Create a place for output images if not exist
3546 #endif
3547 /*
3548 ####################################
3549 ####################################
3550 ####################################
3551 ####################################
3552 2KILL :: END
3553 ####################################
3554 ####################################
3555 ####################################
3556 ####################################
3557 */
3558 
3559 
3560   atexit (TrashSound);
3561 
3562   // In case of crash, try to free as many resources as we can
3563 
3564   //  getchar ();
3565 
3566   // (*fade_out_proc[rand () % nb_fadeout]) (0, 0, 320, 200);
3567 
3568   BaseClock = 7800000;		//7160000; //3.58-21.48;
3569   //  7.8 Mhz  ^
3570 
3571 #if defined(ALLEGRO)
3572   LOCK_VARIABLE (key_delay);
3573   LOCK_VARIABLE (timer_60);
3574   LOCK_VARIABLE (can_blit);
3575   LOCK_VARIABLE (RAM);
3576   LOCK_VARIABLE (list_to_freeze);
3577   LOCK_FUNCTION (interrupt_60hz);
3578 #endif
3579 
3580   IPeriod = BaseClock / (scanlines_per_frame * 60);
3581 #ifndef FINAL_RELEASE
3582   fprintf (stderr, "IPeriod = %d\n", IPeriod);
3583 #endif
3584 //      UPeriod = 0;
3585   // TimerPeriod = BaseClock / 1000 * 3 * 1024 / 21480;
3586 #ifndef FINAL_RELEASE
3587   fprintf (stderr, "TimerPeriod = %d\n", TimerPeriod);
3588 #endif
3589 
3590 /* TEST */
3591   io.screen_h = 224;
3592 /* TEST */
3593   io.screen_w = 256;
3594 
3595   if (osd_init_input () != 0)
3596 	{
3597 		fprintf(stderr, "Initialization of input system failed\n");
3598 		exit(6);
3599 	}
3600 
3601 /*
3602   if (!osd_init_machine ())
3603     return -1;
3604 */
3605 
3606   do
3607     {
3608 
3609 #warning reenable card selection without allegro
3610 #if defined(ALLEGRO)
3611       if ((!cart_name[0]) && (CD_emulation != 1))
3612 	strcpy (cart_name, (char *) select_rom ("*.pce"));
3613 #endif
3614 
3615       if (strcmp (cart_name, "NO FILE"))
3616 	if (!InitPCE (cart_name, backup_mem))
3617 	  {
3618 	    effectively_played = 1;
3619 	    cart_reload = 0;
3620 
3621 #if defined(ALLEGRO)
3622 	    install_int_ex (interrupt_60hz, BPS_TO_TIMER (60));
3623 #endif
3624 
3625 	    RunPCE ();
3626 
3627 #if defined(ALLEGRO)
3628 	    remove_int (interrupt_60hz);
3629 #endif
3630 
3631 	    TrashPCE (backup_mem);
3632 	  }
3633     }
3634   while (cart_reload);
3635 
3636   /* TrashMachine (); */
3637   osd_shut_machine ();
3638 
3639   if (effectively_played)
3640     {
3641       if (builtin_system_used)
3642 	printf ("");
3643 	      else if (NO_ROM < pce_romlist_size)
3644 	printf (MESSAGE[language][played], (pce_romlist + NO_ROM) ? pce_romlist[NO_ROM].name : "Unknown");
3645       else
3646 	printf (MESSAGE[language][unknown_contact_me]);
3647     }
3648   else
3649     printf (MESSAGE[language][C_ya]);
3650 
3651 #ifdef CHRONO
3652   if (!(F = fopen ("RESULT.DAT", "wt+")))
3653     return -1;
3654   for (vmode = 0; vmode < 256; vmode++)
3655     {
3656       fprintf (F,
3657 	       "Inst 0X%02X : %10u calls, %10u (*840)ns => avr. of %10u (*840)ns\n",
3658 	       vmode, nb_used[vmode], time_used[vmode],
3659 	       (nb_used[vmode] ? time_used[vmode] / nb_used[vmode] : 0));
3660       if (nb_used[vmode] >= timax)
3661 	{
3662 	  inst_max = vmode;
3663 	  timax = nb_used[vmode];
3664 	}
3665     };
3666   fprintf (F,
3667 	   "\nGreat Winner is inst 0X%02X with %10u calls and %10u (*840)ns elapsed => average of %10u",
3668 	   inst_max, nb_used[inst_max], time_used[inst_max],
3669 	   time_used[inst_max] / nb_used[inst_max]);
3670   fclose (F);
3671 
3672 #endif
3673 
3674   fprintf (stderr, exit_message);
3675 
3676   if (timer_60)
3677     {
3678       fprintf (stderr, MESSAGE[language][time_elapsed], (timer_60 / 60.0));
3679       fprintf (stderr, MESSAGE[language][frame_per_sec],
3680 	       frame / (timer_60 / 60.0));
3681     }
3682 
3683 #warning move to other osd_machine
3684 	/* Moved to osd_machine (only linux/sdl right now)
3685   if (dump_snd)
3686     fclose (out_snd);
3687 	*/
3688 /*
3689 ####################################
3690 ####################################
3691 ####################################
3692 ####################################
3693 2KILL :: BEGIN
3694 ####################################
3695 ####################################
3696 ####################################
3697 ####################################
3698 */
3699 #if defined(EXTERNAL_DAT) && defined(ALLEGRO)
3700   Log ("I'll unload datafile, @ = %p\n", datafile);
3701 //      if (datafile)
3702 //      unload_datafile(datafile);
3703   Log ("I've unloaded datafile\n");
3704 #endif
3705 /*
3706 ####################################
3707 ####################################
3708 ####################################
3709 ####################################
3710 2KILL :: END
3711 ####################################
3712 ####################################
3713 ####################################
3714 ####################################
3715 */
3716 
3717   Log
3718     ("\n--[ END OF PROGRAM ]----------------------------------\nExecution completed successfully\n");
3719   return 0;
3720 }
3721 
3722 #ifdef ALLEGRO
3723 
3724 END_OF_MAIN ();
3725 
3726 #endif
3727 
3728 #endif
3729