/[projet1]/public/pc/emulators/caloric/src/host.c
Defence Force logotype

Contents of /public/pc/emulators/caloric/src/host.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 148 - (show annotations)
Sun Aug 23 11:20:52 2009 UTC (10 years, 3 months ago) by Jede
File MIME type: text/plain
File size: 16247 byte(s)
Changement de zoom par l'interface
1 /*
2 * host.c - various stuff
3 * FF sometime in 1994-1997
4 */
5
6 /*
7 Parts of this file copyright 1994-1997 Fabrice Francès.
8 Parts of this file copyright 2000-2003 André Majorel.
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of version 2 of the GNU General Public License as published by the
12 Free Software Foundation.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 Place, Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #include <ctype.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <time.h>
31
32 #include <unistd.h>
33 #if HAVE_IOPERM
34 # include <sys/io.h>
35 #endif
36 #include <sys/types.h>
37 #include <sys/stat.h>
38
39 #include "caloric.h"
40 #include "dsp.h"
41 #include "hardware.h"
42 #include "keyb_us.h"
43 #include "traps.h"
44
45
46 static void parse_rcfile (const char *setup, FILE *setup_fp);
47
48 extern char Eprom[8192];
49 extern char Banks[8][16384];
50 extern char RomBank[8];
51 extern int Bank_point;
52 extern int Eprom_start;
53 extern char ram_pattern;
54 extern int Com_port, Com_Addr, serial_desc;
55 extern int cycles,initial_cycles;
56 extern char sound;
57 extern char joystick,joystickport,acia,rtclock,printer;
58 extern char jasmin,telestrat,disk;
59 extern int rs232;
60
61 static char *temppath="";
62 char output_name[64]="", dump_name[128]="";
63 char serial_name[64]="", printer_name[128]="";
64 static char oric1_name[128]="", atmos_name[128]="", bank_name[8][128]={"","","","","","","",""};
65 static char microdisc_name[128]="", jasmin_name[128]="";
66 char atmos=1;
67 char messages[35][41];
68 int quit_on_trap;
69 int zoom;
70 int debugger = 0;
71
72 int machine_changed=0;
73 int zoom_changed=1;
74 int current_machine;
75
76 void Load_ROM(unsigned char *rom_adr)
77 {
78 const char *basename = atmos ? atmos_name : oric1_name;
79 char *pathname;
80 FILE *rom_fp;
81
82 pathname = locate_file (basename, datapath);
83 if (pathname == NULL)
84 {
85 err ("%s: not found", basename);
86 exit (1);
87 }
88 rom_fp = fopen (pathname, "rb");
89 if (rom_fp == NULL)
90 {
91 err ("%s: %s", pathname, strerror (errno));
92 exit (1);
93 }
94 if (fread (rom_adr, 16384, 1, rom_fp) != 1)
95 {
96 err ("%s: read error", pathname);
97 exit (1);
98 }
99 fclose (rom_fp);
100 free (pathname);
101 }
102
103 void Load_EPROM()
104 {
105 const char *basename = jasmin ? jasmin_name : microdisc_name;
106 char *pathname;
107 FILE *eprom_fp;
108 int size;
109
110 pathname = locate_file (basename, datapath);
111 if (pathname == NULL)
112 {
113 err ("%s: not found", basename);
114 exit (1);
115 }
116 eprom_fp = fopen (pathname, "rb");
117 if (eprom_fp == NULL)
118 {
119 err ("%s: %s", pathname, strerror (errno));
120 exit (1);
121 }
122 size = fread (Eprom, 1, 16384, eprom_fp);
123 if (size < 1)
124 {
125 err ("%s: read error", pathname);
126 exit (1);
127 }
128 if (size < 16384)
129 memcpy (Eprom + 16384 - size, Eprom, size);
130 Eprom_start = 0x10000 - size;
131 Bank_point = Eprom_start;
132 fclose (eprom_fp);
133 free (pathname);
134 }
135
136 /*****************************************************************************/
137 void Load_Banks()
138 {
139 int i, size;
140 for (i = 1; i < 8; i++)
141 {
142 char *pathname;
143 if (bank_name[i][0]=='\0')
144 continue;
145 pathname = locate_file (bank_name[i], datapath);
146 if (pathname == NULL)
147 {
148 err ("bank #%d: %s: not found", i, pathname);
149 }
150 else
151 {
152 FILE *rom_fp = fopen (pathname, "rb");
153 if (rom_fp == NULL)
154 {
155 err ("bank #%d: %s: %s", i, pathname, strerror (errno));
156 }
157 else
158 {
159 RomBank[i] = 1;
160 size = fread (Banks[i], 1, 16384, rom_fp);
161 if (size < 16384)
162 memcpy ((char *) (Banks + i) + 16384 - size, Banks + i, size);
163 fclose (rom_fp);
164 }
165 free (pathname);
166 }
167 }
168 Bank_point=0xC000;
169 if (!RomBank[7]) {
170 err ("no bank #7");
171 err ("check your caloricrc");
172 exit(1);
173 }
174 }
175
176 /***************************************************************************/
177 char tape_name[256]="";
178 extern FILE *tape_handle;
179 extern char protected_tape;
180
181 int Open_Tape(const char *name)
182 {
183 err ("Open_Tape(%s)", name); /* FIXME DEBUG */
184 if (tape_handle) Close_Tape();
185 protected_tape=0;
186 tape_handle=fopen(name,"r+b");
187 if (tape_handle==NULL) {
188 tape_handle=fopen(name,"rb");
189 if (tape_handle==NULL) return 0;
190 protected_tape=1;
191 }
192 strcpy(tape_name,name);
193 return 1;
194 }
195
196 void protect_tape(void)
197 {
198 if (!tape_handle) return;
199 fclose(tape_handle);
200 tape_handle=NULL;
201 chmod(tape_name,0444);
202 Open_Tape(tape_name);
203 }
204
205 void unprotect_tape(void)
206 {
207 if (!tape_handle) return;
208 fclose(tape_handle);
209 tape_handle=NULL;
210 chmod(tape_name,0644);
211 Open_Tape(tape_name);
212 }
213
214 void Close_Tape(void)
215 {
216 err ("Close_Tape()"); /* FIXME DEBUG */
217 if (tape_handle) fclose(tape_handle);
218 tape_handle=NULL;
219 tape_name[0]=0;
220 }
221
222 void Create_Tape(void)
223 {
224 if (tape_handle) fclose(tape_handle);
225 tape_name[0]=0;
226 protected_tape=0;
227 tape_handle=fopen("________","w+b");
228 if (tape_handle==NULL) return;
229 strcpy(tape_name,"________");
230 }
231
232 /***************************************************************************/
233
234 /***************************************************************************/
235 extern int nbdisks;
236 extern char diskbuf[8192];
237 extern FILE *fd[4];
238 extern char write_only[4];
239 extern char drives[4];
240
241 static int current_drive;
242 static char diskid[8];
243 static int sides[4];
244 static int tracks[4];
245 static int geometry[4]; /* 1 : whole side 0 first */
246 static char disk_signature[]="MFM_DISK";
247 char disk_name[4][256]={ "", "", "", "" };
248
249 int Open_Disk(char *name,int drive)
250 {
251 Close_Disk(drive);
252 write_only[drive]=0;
253 fd[drive]=fopen(name,"r+b");
254 if (fd[drive]==NULL) {
255 fd[drive]=fopen(name,"rb");
256 if (fd[drive]==NULL) return 0;
257 write_only[drive]=1;
258 }
259 fread(diskid,8,1,fd[drive]);
260 if (strncmp(diskid,disk_signature,8)!=0) {
261 err("%s is not an Oric disk image",name);
262 return 0;
263 }
264 fread(&sides[drive],1,4,fd[drive]);
265 fread(&tracks[drive],1,4,fd[drive]);
266 fread(&geometry[drive],1,4,fd[drive]);
267 strcpy(disk_name[drive],name);
268 return 1;
269 }
270
271 void Close_Disk(int drive)
272 {
273 if (fd[drive]) fclose(fd[drive]);
274 fd[drive]=NULL;
275 disk_name[drive][0]=0;
276 }
277
278 int Create_Disk(int drive)
279 {
280 if (fd[drive]) fclose(fd[drive]);
281 disk_name[drive][0]=0;
282 write_only[drive]=0;
283 fd[drive]=fopen("________.dsk","w+b");
284 if (fd[drive]==NULL) return 0;
285 strcpy(disk_name[drive],"________.dsk");
286 return 1;
287 }
288
289 void disk_flushbuf(void)
290 {
291 if (fd[current_drive]!=NULL) {
292 fwrite(diskbuf,6400,1,fd[current_drive]);
293 fseek(fd[current_drive],-6400,SEEK_CUR);
294 }
295 }
296
297
298 void disk_read_track(int drive,int side,int track)
299 {
300 long offset=(side*tracks[drive]+track)*6400+256;
301 current_drive=drive;
302 memset(diskbuf,0,6400);
303 if (fd[drive]!=NULL) {
304 fseek(fd[drive],offset,SEEK_SET);
305 fread(diskbuf,6400,1,fd[drive]);
306 fseek(fd[drive],-6400,SEEK_CUR);
307 }
308 }
309
310 int disk_format(int drive,int side,int track)
311 {
312 long offset;
313 if (fd[drive]==NULL) {
314 if (Create_Disk(drive)==0) return 1;
315 }
316 if (write_only[drive]) return 1;
317 if (side+1>sides[drive]) sides[drive]=side+1;
318 if (track+1>tracks[drive]) tracks[drive]=track+1;
319 offset=(side*tracks[drive]+track)*6400+256;
320 fseek(fd[drive],0,SEEK_SET);
321 fwrite(disk_signature,8,1,fd[drive]);
322 fwrite(&sides[drive],4,1,fd[drive]);
323 fwrite(&tracks[drive],4,1,fd[drive]);
324 fwrite(&geometry,4,1,fd[drive]);
325 fseek(fd[drive],offset,SEEK_SET);
326 fwrite(diskbuf,6400,1,fd[drive]);
327 return 0;
328 }
329
330 /***************************************************************************/
331
332 void Save_hardcopy()
333 {
334
335 }
336
337 /***************************************************************************/
338 extern char State[64];
339 static const char dump_pathname[] = "Dump"; /* FIXME use dump_name instead ? */
340
341 void Dump(char *mem)
342 {
343 FILE *dump_fd;
344 dump_fd=fopen(dump_pathname,"wb");
345 if (dump_fd!=NULL) {
346 fwrite(mem,1,65536,dump_fd);
347 fwrite(State,1,64,dump_fd);
348 fclose(dump_fd);
349 }
350 }
351
352 void Load_Dump(unsigned char *mem)
353 {
354 FILE *dump_fd;
355 dump_fd=fopen(dump_pathname,"rb");
356 if (dump_fd==NULL) {
357 err("%s: %s",dump_pathname,strerror(errno));
358 err("Dump file %s does not exist",dump_pathname);
359 err("(Please check caloricrc)");
360 exit(1);
361 }
362 fread(mem,1,65536,dump_fd);
363 fread(State,1,64,dump_fd);
364 fclose(dump_fd);
365 }
366
367 /***************************************************************************/
368
369 static FILE *printfd=NULL;
370
371 void Start_Printer()
372 {
373 printfd=fopen(printer_name,"wb");
374 if (printfd==NULL) {
375 err("%s: %s",printer_name,strerror(errno));
376 err("Can't open printer output %s",printer_name);
377 err("(Please check it or modify caloricrc)");
378 exit(1);
379 }
380 }
381
382 void Printer(char c)
383 {
384 if (printfd) putc(c,printfd);
385 }
386
387 /***************************************************************************/
388 void Start_RS232(void)
389 {
390 if (*serial_name == '\0') {
391 serial_desc = -1;
392 }
393 else {
394 #ifdef O_NDELAY
395 serial_desc=open(serial_name,O_RDWR | O_NDELAY);
396 #else
397 #ifdef O_NONBLOCK
398 serial_desc=open(serial_name,O_RDWR | O_NONBLOCK);
399 #else
400 serial_desc = -1;
401 #endif
402 #endif
403 if (serial_desc==-1) {
404 err("%s: %s",serial_name,strerror(errno));
405 err("Can't open communication port %s",serial_name);
406 err("(Please check it or modify caloricrc)");
407 exit(1);
408 }
409 }
410 }
411 /***************************************************************************/
412
413 int init(int argc, char *argv[])
414 {
415 int speed_index,restart=0;
416 int g;
417 zoom = 1;
418 debugger=1;
419 current_machine=1;
420 while ((g = getopt (argc, argv, "1aA:djJpQrs:S:tX:z:g")) != EOF) {
421 if (g == '1') { telestrat=0; atmos=0; current_machine=0; }
422 else if (g == 'a') { telestrat=0; atmos=1; current_machine=1;}
423 else if (g == 'A') { audio_device=optarg; }
424 else if (g == 'd') { disk=1; }
425 else if (g == 'j') { telestrat=0; jasmin=1; disk=1; }
426 else if (g == 'J') { joystickport=1; }
427 else if (g == 'p') { joystick=1; disable_keypad(); }
428 else if (g == 'Q') { quit_on_trap = 1; }
429 else if (g == 'r') { restart=1; }
430 else if (g == 'g') { debugger=1; }
431 else if (g == 's') {
432 sscanf (optarg, "%d", &speed_index);
433 if (speed_index<10) {
434 err("Speed index of %d%% ? Surely you're "
435 "joking, Mr. Feynman...",speed_index);
436 exit(1);
437 }
438 initial_cycles=cycles=200*speed_index;
439 }
440 else if (g == 'S') {
441 if (strcmp (optarg, "sdl") == 0)
442 audio_method = AM_SDL;
443 else if (strcmp (optarg, "arts") == 0)
444 audio_method = AM_ARTS;
445 else if (strcmp (optarg, "auto") == 0)
446 audio_method = AM_ARTS_OSS;
447 else if (strcmp (optarg, "oss") == 0)
448 audio_method = AM_OSS;
449 else if (strcmp (optarg, "alsa") == 0)
450 audio_method = AM_ALSA;
451
452 else {
453 err ("the sound output method must be \"alsa\", \"arts\""
454 ", \"auto\" or \"oss\"");
455 exit (1);
456 }
457 }
458 else if (g == 't') { telestrat=1; disk=1; current_machine=2;}
459
460 else if (g == 'z')
461 {
462 zoom = atoi(optarg);
463 if (zoom < 1)
464 {
465 err ("the zoom factor must be greater than 1");
466 exit (1);
467 }
468 }
469 else
470 exit(1);
471 }
472 {
473 int n;
474
475 for (n = optind; n < argc; n++)
476 if (Open_Disk(argv[n],nbdisks++))
477 disk=1;
478 }
479
480 if (telestrat) { disk=1; jasmin=0; acia=1; }
481 if (jasmin) { disk=1; }
482
483 if (joystick) joystickport=0;
484 if (printer) Start_Printer();
485 if (acia && *serial_name != '\0')
486 {
487 #if HAVE_IOPERM
488 if (ioperm(0x3f8, 8, 1) != 0) /* ttyS0 */
489 {
490 err("ioperm(0x3f8,8): %s, disabling 6551 emulation",
491 strerror (errno));
492 goto rs232_fini;
493 }
494 if (ioperm(0x2f8, 8, 1) != 0) /* ttyS1 */
495 {
496 err("ioperm(0x2f8,8): %s, disabling 6551 emulation",
497 strerror (errno));
498 goto rs232_fini;
499 }
500 rs232 = 1;
501 rs232_fini:
502 ;
503 #else
504 err("ioperm not available on this platform,"
505 " disabling 6551 emulation");
506 #endif
507 }
508 if (rs232) Start_RS232();
509
510
511
512 Init_Hard();
513 if (telestrat) {
514 Load_Banks();
515 } else {
516 if (disk) {
517 Load_EPROM();
518 }
519 Load_ROM(Oric_Mem+0x10000);
520 }
521 if (restart) Load_Dump(Oric_Mem);
522 Patch_ROM();
523 return restart;
524 }
525
526 void redirect_output(void)
527 {
528 sprintf(output_name,"/tmp/euphoric.lst");
529 freopen(output_name,"w",stdout);
530 rewind(stdout);
531 }
532
533 void delete_output(void)
534 {
535 unlink(output_name);
536 }
537
538 void remove_eol(char *str)
539 {
540 int i;
541 for(i=strlen(str)-1; str[i]==' ' || str[i]=='\r' || str[i]=='\n'; i--)
542 str[i]='\0';
543 }
544
545 void setup(char *env[])
546 {
547 int i;
548 const char **p;
549 int count = 0;
550 FILE *fp;
551 for (i = 0; i < 35; i++)
552 messages[i][0] = 0;
553 for(i=0;env[i]!=NULL;i++)
554 {
555 if (strncmp (env[i], "TEMP=", 5) == 0)
556 temppath = (&env[i][5]);
557 }
558
559 for (p = rcfiles; *p != NULL; p++)
560 {
561
562 char *pathname = NULL;
563
564 pathname = expand_path (*p);
565 #ifdef DEBUG_RELEASE
566 printf("Trying to find %s in %s\n",*p,pathname);
567 #endif
568
569 fp = fopen (pathname, "r");
570 if (fp == NULL)
571 {
572 if (errno != ENOENT)
573 err("warning: %s: %s", pathname, strerror (errno));
574 #ifdef DEBUG_RELEASE
575 printf("Can't found %s\n",pathname);
576 #endif
577
578
579 }
580 else
581 {
582 parse_rcfile (pathname, fp);
583 #ifdef DEBUG_RELEASE
584 printf("Reading %s\n",pathname);
585 #endif
586 count++;
587 fclose (fp);
588 }
589 free (pathname);
590 }
591 // #endif
592 if (count == 0)
593 err("warning: no config file found");
594 }
595
596 static void parse_rcfile (const char *setup, FILE *setup_fp)
597 {
598 char line[256];
599 float frequency;
600
601 while(!feof(setup_fp)) {
602 fgets(line,256,setup_fp);
603 remove_eol(line);
604 if (strncmp(line,"Computer=",9)==0) {
605 if (strcmp(line+9,"Oric1")==0)
606 ;
607 else if (strcmp(line+9,"Atmos")==0)
608 atmos=1;
609 else if (strcmp(line+9,"Telestrat")==0 || strcmp(line+9,"Stratos")==0)
610 telestrat=1;
611 } else if (strncmp(line,"DiskController=",15)==0) {
612 if (strcmp(line+15,"Microdisc")==0)
613 disk=1;
614 else if (strcmp(line+15,"Jasmin")==0)
615 jasmin=1;
616 } else if (strncmp(line,"Oric1Rom=",9)==0) {
617 strcpy(oric1_name,line+9);
618 } else if (strncmp(line,"AtmosRom=",9)==0) {
619 strcpy(atmos_name,line+9);
620 } else if (strncmp(line,"MicrodiscEprom=",15)==0) {
621 strcpy(microdisc_name,line+15);
622 } else if (strncmp(line,"JasminEprom=",12)==0) {
623 strcpy(jasmin_name,line+12);
624 } else if (strncmp(line,"Bank7=",6)==0) {
625 strcpy(bank_name[7],line+6);
626 } else if (strncmp(line,"Bank6=",6)==0) {
627 strcpy(bank_name[6],line+6);
628 } else if (strncmp(line,"Bank5=",6)==0) {
629 strcpy(bank_name[5],line+6);
630 } else if (strncmp(line,"Bank4=",6)==0) {
631 strcpy(bank_name[4],line+6);
632 } else if (strncmp(line,"Bank3=",6)==0) {
633 strcpy(bank_name[3],line+6);
634 } else if (strncmp(line,"Bank2=",6)==0) {
635 strcpy(bank_name[2],line+6);
636 } else if (strncmp(line,"Bank1=",6)==0) {
637 strcpy(bank_name[1],line+6);
638 } else if (strncmp(line,"RamPattern=",11)==0) {
639 ram_pattern=line[11]&1;
640 } else if (strncmp(line,"DriveA=",7)==0) {
641 drives[0]=(line[7]!='N' && line[7]!='n');
642 } else if (strncmp(line,"DriveB=",7)==0) {
643 drives[1]=(line[7]!='N' && line[7]!='n');
644 } else if (strncmp(line,"DriveC=",7)==0) {
645 drives[2]=(line[7]!='N' && line[7]!='n');
646 } else if (strncmp(line,"DriveD=",7)==0) {
647 drives[3]=(line[7]!='N' && line[7]!='n');
648 } else if (strncmp(line,"Clock=",6)==0) {
649 sscanf(line+6,"%f",&frequency);
650 initial_cycles=cycles=((int)(frequency*10.0))*2000;
651 } else if (strncmp(line,"AsynchronousController=",23)==0) {
652 acia=(line[23]!='N' && line[23]!='n');
653 } else if (strncmp(line,"SerialPort=",11)==0) {
654 strcpy(serial_name,line+11);
655 } else if (strncmp(line,"RealTimeClock=",14)==0) {
656 rtclock=(line[14]!='N' && line[14]!='n');
657 } else if (strncmp(line,"Joystick=",9)==0) {
658 joystick=(line[9]!='N' && line[9]!='n');
659 } else if (strncmp(line,"JoystickPort=",13)==0) {
660 joystickport=(line[13]!='N' && line[13]!='n');
661 } else if (strncmp(line,"Printer=",8)==0) {
662 printer=(line[8]!='N' && line[8]!='N');
663 } else if (strncmp(line,"PrinterOutput=",14)==0) {
664 strcpy(printer_name,line+14);
665 } else if (strncmp(line,"DumpFile=",9)==0) {
666 strcpy(dump_name,line+9);
667 } else if (line[0]>='0' && line[0]<='9' && line[1]>='0' && line[1]<='9' && line[2]=='=') {
668 int number=(line[0]-'0')*10+line[1]-'0';
669 if (number<35) {
670 strncpy(messages[number],line+3,41);
671 messages[number][40]=0;
672 }
673 }
674 }
675 }

  ViewVC Help
Powered by ViewVC 1.1.26