/** fMSX: portable MSX emulator ******************************/ /** **/ /** fMSX.c **/ /** **/ /** This file contains generic main() procedure statrting **/ /** the emulation. **/ /** **/ /** Copyright (C) Marat Fayzullin 1994-2002 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ #include "MSX.h" #include "Help.h" #ifdef SDL #include #endif #ifdef MSDOS #include "LibMSDOS.h" #endif #include #include #include #include char *Options[]= { "verbose","hperiod","vperiod","uperiod","pal","ntsc","help", "printer","serial","diska","diskb","tape","font","logsnd","state", "ram","vram","rom","auto","noauto","msx1","msx2","msx2+","joy", "home","trap","sound","nosound","shm","noshm","saver","nosaver", "scale","sync","nosync","static","nostatic","vsync","240","200", #ifdef SDL "msxmusic","msxaudio","buffer","lowres","filter","stereo", #endif 0 }; extern char *Title; /* Program title */ extern int UseSound; /* Sound mode (#ifdef SOUND) */ extern int UseSHM; /* Use SHM X extension (#ifdef MITSHM) */ extern int UseZoom; /* Zoom factor (#ifdef UNIX) */ extern int SaveCPU; /* Pause when inactive (#ifdef UNIX) */ extern int UseStatic; /* Use static colors (MSDOS & UNIX) */ extern int SyncScreen; /* Sync screen updates (#ifdef MSDOS) */ extern int FullScreen; /* Use 256x240 screen (#ifdef MSDOS) */ extern int SyncFreq; /* Sync screen updates (#ifdef UNIX) */ extern int SndBufSize; /* Size of audio buffer (#ifdef SDL) */ extern int ARGC; /* argc/argv from main (#ifdef UNIX) */ extern char **ARGV; /** Zero-terminated arrays of disk names for each drive ******/ extern char *Disks[2][MAXDISKS+1]; /** main() ***************************************************/ /** This is a main() function used in Unix and MSDOS ports. **/ /** It parses command line arguments, sets emulation **/ /** parameters, and passes control to the emulation itself. **/ /*************************************************************/ int main(int argc,char *argv[]) { int CartCount,TypeCount; int JoyCount,DiskCount[2]; int N,J; #ifdef DEBUG CPU.Trap = 0xFFFF; CPU.Trace = 0; #endif #ifdef UNIX ARGC = argc; ARGV = argv; #endif #ifdef MSDOS /* No separate console, so no messages */ Verbose=0; /* Figure out program directory name */ ProgDir=GetPath(argv[0]); #else Verbose=1; #endif #ifdef SDL #ifndef UNIX Verbose=0; #endif #endif /* Clear everything */ CartCount=TypeCount=JoyCount=0; DiskCount[0]=DiskCount[1]=0; /* Default disk images */ Disks[0][1]=Disks[1][1]=0; Disks[0][0]=DiskA; Disks[1][0]=DiskB; for(N=1;N=argc) printf("%s: No HBlank period supplied\n",argv[0]); else { J=atoi(argv[N]); if((J>=30)&&(J<=3000)) HPeriod=J; } break; case 2: N++; if(N>=argc) printf("%s: No VBlank period supplied\n",argv[0]); else { J=atoi(argv[N]); if((J>=1000)&&(J<=100000)) VPeriod=J; if((J>=256)&&(J<=999)) VPeriod=HPeriod*J; } break; case 3: N++; if(N>=argc) printf("%s: No screen update period supplied\n",argv[0]); else { J=atoi(argv[N]); if((J>=1)&&(J<=20)) UPeriod=J; } break; case 4: VPeriod=VPERIOD_PAL/6; HPeriod=HPERIOD/6; break; case 5: VPeriod=VPERIOD_NTSC/6; HPeriod=HPERIOD/6; break; #ifndef SDL case 6: printf ("%s by Marat Fayzullin (C)FMS 1994-2002\n",Title); for(J=0;HelpText[J];J++) puts(HelpText[J]); return(0); case 7: N++; if(N=argc) printf("%s: No file for drive A\n",argv[0]); else if(DiskCount[0]>=MAXDISKS) printf("%s: Too many disks for drive A\n",argv[0]); else Disks[0][DiskCount[0]++]=argv[N]; break; case 10: N++; if(N>=argc) printf("%s: No file for drive B\n",argv[0]); else if(DiskCount[1]>=MAXDISKS) printf("%s: Too many disks for drive B\n",argv[0]); else Disks[1][DiskCount[1]++]=argv[N]; break; case 11: N++; if(N=argc) printf("%s: No number of RAM pages supplied\n",argv[0]); else RAMPages=atoi(argv[N]); break; case 16: N++; if(N>=argc) printf("%s: No number of VRAM pages supplied\n",argv[0]); else VRAMPages=atoi(argv[N]); break; case 17: N++; if(N>=argc) printf("%s: No ROM mapper type supplied\n",argv[0]); else switch(TypeCount++) { case 0: ROMTypeA=ROMTypeB=atoi(argv[N]);break; case 1: ROMTypeB=atoi(argv[N]);break; default: printf("%s: Excessive -rom option\n",argv[0]); } break; case 18: AutoFire=1;break; case 19: AutoFire=0;break; case 20: MSXVersion=0;break; case 21: MSXVersion=1;break; case 22: MSXVersion=2;break; case 23: N++; if(N>=argc) printf("%s: No joystick type supplied\n",argv[0]); else switch(JoyCount++) { case 0: JoyTypeA=atoi(argv[N]);break; case 1: JoyTypeB=atoi(argv[N]);break; default: printf("%s: Excessive -joy option\n",argv[0]); } break; case 24: N++; if(N>=argc) printf("%s: No home directory name supplied\n",argv[0]); else ProgDir=argv[N]; break; #ifndef SDL #ifdef DEBUG case 25: N++; if(N>=argc) printf("%s: No trap address supplied\n",argv[0]); else if(!strcmp(argv[N],"now")) CPU.Trace=1; else sscanf(argv[N],"%hX",&(CPU.Trap)); break; #endif #ifdef SOUND case 26: N++; if(N>=argc) { UseSound=1;N--; } else if(sscanf(argv[N],"%d",&UseSound)!=1) { UseSound=1;N--; } break; case 27: UseSound=0;break; #endif #ifdef UNIX #ifdef MITSHM case 28: UseSHM=1;break; case 29: UseSHM=0;break; #endif case 30: SaveCPU=1;break; case 31: SaveCPU=0;break; case 32: N++; if(N5 || UseFilter<0) { printf("%s: Invalid filter mode supplied\n",argv[0]); UseFilter=0; } break; case 45: UseStereo=1;break; #endif /* SDL */ default: printf("%s: Wrong option '%s'\n",argv[0],argv[N]); } } /* Terminate disk lists and set initial disk names */ if(DiskCount[0]) { Disks[0][DiskCount[0]]=0;DiskA=Disks[0][0]; } if(DiskCount[1]) { Disks[1][DiskCount[1]]=0;DiskB=Disks[1][0]; } /* Start fMSX! */ if(!InitMachine()) return(1); StartMSX(); TrashMSX(); TrashMachine(); return(0); }