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