Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

c64_epoc32.i

Go to the documentation of this file.
00001 /*
00002  *  C64_epoc32.i - EPOC32 specific stuff
00003  *
00004  *  Frodo (C) 1994-1997 Christian Bauer
00005  *
00006  *  -> ported to Epoc32 by Alfred E. Heggestad & Jal Panvel (c) 1999-2000
00007  */
00008 
00009 #include <process.h>
00010 #include "main.h"
00011 #include "sys/time.h"
00012 
00013 #ifndef BOOL
00014 #define BOOL bool
00015 #endif
00016 
00017 #define DWORD long
00018 
00019 #define FRAME_INTERVAL          (1000/SCREEN_FREQ)      // in milliseconds
00020 #ifdef FRODO_SC
00021 #define SPEEDOMETER_INTERVAL    4000                    // in milliseconds
00022 #else
00023 #define SPEEDOMETER_INTERVAL    1000                    // in milliseconds
00024 #endif
00025 #define JOYSTICK_SENSITIVITY    40                      // % of live range
00026 #define JOYSTICK_MIN            0x0000                  // min value of range
00027 #define JOYSTICK_MAX            0xffff                  // max value of range
00028 #define JOYSTICK_RANGE          (JOYSTICK_MAX - JOYSTICK_MIN)
00029 
00030 
00031 
00032 #ifndef HAVE_USLEEP
00033 /*
00034  *  NAME:
00035  *      usleep     -- This is the precision timer for Test Set
00036  *                    Automation. It uses the select(2) system
00037  *                    call to delay for the desired number of
00038  *                    micro-seconds. This call returns ZERO
00039  *                    (which is usually ignored) on successful
00040  *                    completion, -1 otherwise.
00041  *
00042  *  ALGORITHM:
00043  *      1) We range check the passed in microseconds and log a
00044  *         warning message if appropriate. We then return without
00045  *         delay, flagging an error.
00046  *      2) Load the Seconds and micro-seconds portion of the
00047  *         interval timer structure.
00048  *      3) Call select(2) with no file descriptors set, just the
00049  *         timer, this results in either delaying the proper
00050  *         ammount of time or being interupted early by a signal.
00051  *
00052  *  HISTORY:
00053  *      Added when the need for a subsecond timer was evident.
00054  *
00055  *  AUTHOR:
00056  *      Michael J. Dyer                   Telephone:   AT&T 414.647.4044
00057  *      General Electric Medical Systems        GE DialComm  8 *767.4044
00058  *      P.O. Box 414  Mail Stop 12-27         Sect'y   AT&T 414.647.4584
00059  *      Milwaukee, Wisconsin  USA 53201                      8 *767.4584
00060  *      internet:  mike@sherlock.med.ge.com     GEMS WIZARD e-mail: DYER
00061  */
00062 
00063 #include <unistd.h>
00064 
00065 #ifdef USE_STDLIB
00066 #include <stdlib.h>
00067 #include <stdio.h>
00068 #include <errno.h>
00069 #endif
00070 
00071 #include <time.h>
00072 #include <sys/time.h>
00073 #include <sys/param.h>
00074 #include <sys/types.h>
00075 
00076 int usleep(unsigned long int microSeconds)
00077 {
00078         unsigned int            Seconds, uSec;
00079         int                     nfds, readfds, writefds, exceptfds;
00080         struct  timeval         Timer;
00081 
00082         nfds = readfds = writefds = exceptfds = 0;
00083 
00084         if( (microSeconds == (unsigned long) 0)
00085                 || microSeconds > (unsigned long) 4000000 )
00086         {
00087 #ifdef USE_STDLIB
00088                 errno = ERANGE;         /* value out of range */
00089 #else
00090 #endif
00091                 perror( "usleep time out of range ( 0 -> 4000000 ) " );
00092                 return -1;
00093         }
00094 
00095         Seconds = microSeconds / (unsigned long) 1000000;
00096         uSec    = microSeconds % (unsigned long) 1000000;
00097 
00098         Timer.tv_sec            = Seconds;
00099         Timer.tv_usec           = uSec;
00100 
00101         return 0;
00102 }
00103 #endif
00104 
00105 
00106 
00107 void C64::c64_ctor1()
00111         {
00112 #if _DEBUG
00113         vic_time = 0;
00114 #endif
00115         }
00116 
00117 
00118 void C64::c64_ctor2()
00119         {
00120         }
00121 
00122 
00123 void C64::c64_dtor()
00124 /*
00125  *  Destructor, system-dependent things
00126  */
00127         {
00128         }
00129 
00130 
00131 void C64::Run()
00135         {
00136         TheCPU->Reset();
00137         TheSID->Reset(); 
00138         TheCIA1->Reset();
00139         TheCIA2->Reset();
00140         TheCPU1541->Reset();
00141 
00142         // Patch kernal IEC routines
00143         orig_kernal_1d84 = Kernal[0x1d84];
00144         orig_kernal_1d85 = Kernal[0x1d85];
00145     PatchKernal(ThePrefs.FastReset, ThePrefs.Emul1541Proc);
00146 
00147         // Start the CPU thread
00148         }
00149 
00150 
00151 void C64::Quit()
00155         {
00156         quit_thyself = TRUE;
00157         }
00158 
00159 
00160 
00161 void C64::VBlank(bool draw_frame)
00165         {
00166         // Poll keyboard
00167         TheDisplay->PollKeyboard(TheCIA1->KeyMatrix, TheCIA1->RevMatrix, &joykey);
00168         if (TheDisplay->quit_requested)
00169                 quit_thyself = true;
00170 
00171         // Poll joysticks
00172         if (ThePrefs.Joystick1On)
00173                 TheCIA1->Joystick1 = poll_joystick(0);
00174         if (ThePrefs.Joystick2On)
00175                 TheCIA1->Joystick2 = poll_joystick(1);
00176 
00177 //      TheCIA1->Joystick1 = 0xff;
00178 //      TheCIA1->Joystick2 = 0xff;
00179 
00180 #ifndef __SYMBIAN32__
00181         if (ThePrefs.JoystickSwap) {
00182                 uint8 tmp = TheCIA1->Joystick1;
00183                 TheCIA1->Joystick1 = TheCIA1->Joystick2;
00184                 TheCIA1->Joystick2 = tmp;
00185         }
00186 #endif
00187 
00188        
00189         // Count TOD clocks
00190         TheCIA1->CountTOD();
00191         TheCIA2->CountTOD();
00192 
00193         // Update window if needed
00194         if (draw_frame)
00195                 {
00196         TheDisplay->Update();
00197 
00198 #ifdef BACKGND_UPDATE
00199                 if(TheVIC->ec_changed > 0)      // reset flag
00200                         --TheVIC->ec_changed;
00201 #endif
00202                 // Calculate time between VBlanks, display speedometer
00203                 struct timeval tv;
00204 #ifdef USE_STDLIB
00205                 gettimeofday(&tv, NULL);
00206 #else
00207                 tv.tv_usec = User::TickCount() * 15625;
00208                 tv.tv_sec = tv.tv_usec / 1000000;
00209                 tv.tv_usec %= 1000000;
00210 #endif
00211                 
00212                 
00213                 if ((tv.tv_usec -= tv_start.tv_usec) < 0) {
00214                         tv.tv_usec += 1000000;
00215                         tv.tv_sec -= 1;
00216                 }
00217                 tv.tv_sec -= tv_start.tv_sec;
00218                 double elapsed_time = (double)tv.tv_sec * 1000000 + tv.tv_usec;
00219                 speed_index = 20000 / (elapsed_time + 1) * ThePrefs.SkipFrames * 100;
00220 
00221                 // Limit speed to 100% if desired
00222                 if ((speed_index > 100) && ThePrefs.LimitSpeed) {
00223                         usleep((unsigned long)(ThePrefs.SkipFrames * 20000 - (long)elapsed_time));      //AEH 991030
00224                         speed_index = 100;
00225                 }
00226 
00227 #ifdef USE_STDLIB
00228                 gettimeofday(&tv_start, NULL);
00229 #else
00230                 tv_start.tv_usec = User::TickCount() * 15625;
00231                 tv_start.tv_sec = tv_start.tv_usec / 1000000;
00232                 tv_start.tv_usec %= 1000000;
00233 #endif
00234 
00235                 TheDisplay->Speedometer((int)speed_index);
00236                 }
00237 
00238 #ifdef __SYMBIAN32__
00239         
00240         //
00241         // handle asyncronous snapshots
00242         // the dialogs are now done in the AppUi class
00243         //
00244         CE32FrodoAppUi* appui = iFrodoPtr->iDocPtr->iAppUiPtr;
00245         __CHECK_NULL(appui);
00246 
00247         switch(appui->iSnapState)
00248                 {
00249         case ESnapShotSave:
00250                 {
00256                 if(appui->iCurrentFile.Length())
00257                         SaveSnapshot((char*)appui->iCurrentFile.PtrZ());
00258                 appui->iSnapState = ESnapShotIdle;
00259                 }
00260                 break;
00261 
00262         case ESnapShotLoad:
00263                 {
00264                 if(appui->iCurrentFile.Length())
00265                         LoadSnapshot((char*)appui->iCurrentFile.PtrZ());
00266                 appui->iSnapState = ESnapShotIdle;
00267                 }
00268                 break;
00269 
00270         case ESnapShotIdle:
00271                 default:
00272                 break;
00273                 }
00274 
00275 #endif // __SYMBIAN32__
00276         
00277         }
00278 
00279 
00280 
00281 /*
00282  *  Open/close joystick drivers given old and new state of
00283  *  joystick preferences
00284  */
00285 
00286 
00287 /*
00288  *  Poll joystick port, return CIA mask
00289  */
00290 uint8 C64::poll_joystick(int port)
00291 {
00292         return joykey;
00293 
00294         //TODO: insert Joystick input types here:
00295 
00296 //      uint8 j=0xff;
00297 //      if (port==1) j=iJoyPadObserver->GetJoyPadState();
00298 //      return j;
00299 
00300 }
00301 
00302 
00303 bool C64::TogglePause(void)
00307         {
00308         have_a_break = !have_a_break;
00309         if (have_a_break) 
00310                 iSoundHaveBeenPaused = ETrue;
00311         else
00312                 iFrodoPtr->StartC64();
00313         return have_a_break;
00314         }
00315 
00316 bool C64::Paused()
00320 {
00321         return have_a_break;
00322 }
00323 
00324 void C64::thread_func()
00325 {
00326         for(TInt i=0;i<TOTAL_RASTERS;i++)
00327                 {
00328 
00329                 int cycles = TheVIC->EmulateLine();
00330 
00331                 TheSID->EmulateLine();
00332 
00333                 TheCIA1->EmulateLine(ThePrefs.CIACycles);
00334                 TheCIA2->EmulateLine(ThePrefs.CIACycles);
00335 
00336                 if (ThePrefs.Emul1541Proc) {
00337                         int cycles_1541 = ThePrefs.FloppyCycles;
00338                         TheCPU1541->CountVIATimers(cycles_1541);
00339 
00340                         if (!TheCPU1541->Idle) {
00341                                 // 1541 processor active, alternately execute
00342                                 //  6502 and 6510 instructions until both have
00343                                 //  used up their cycles
00344                                 while (cycles >= 0 || cycles_1541 >= 0)
00345                                         if (cycles > cycles_1541)
00346                                                 cycles -= TheCPU->EmulateLine(1);
00347                                         else
00348                                                 cycles_1541 -= TheCPU1541->EmulateLine(1);
00349                         } else
00350                                 TheCPU->EmulateLine(cycles);
00351                 } else
00352 
00353                 // 1541 processor disabled, only emulate 6510
00354                 TheCPU->EmulateLine(cycles);
00355 
00356         }
00357         
00358 } // end, C64::thread_func
00359 
00360 
00361 
00362 // EOF - C64_epoc32.i

Generated on Tue Feb 8 04:07:23 2005 for E32frodo by doxygen 1.3.3