1.1 diff -r ea417ac1d83a -r bea459bc22a8 src/main.c 1.2 --- a/src/main.c Tue Nov 30 01:51:22 2010 +0000 1.3 +++ b/src/main.c Wed Dec 01 21:29:44 2010 +0000 1.4 @@ -5,8 +5,9 @@ 1.5 #include <malloc.h> 1.6 #include <string.h> 1.7 1.8 +#include "SDL.h" 1.9 + 1.10 #include "musashi/m68k.h" 1.11 - 1.12 #include "version.h" 1.13 #include "state.h" 1.14 1.15 @@ -179,40 +180,74 @@ 1.16 // 512K of RAM 1.17 state_init(512*1024); 1.18 1.19 - // set up musashi 1.20 + // set up musashi and reset the CPU 1.21 m68k_set_cpu_type(M68K_CPU_TYPE_68010); 1.22 m68k_pulse_reset(); 1.23 - 1.24 - char dasm[512]; 1.25 - m68k_disassemble(dasm, 0x80001a, M68K_CPU_TYPE_68010); 1.26 - printf("%s\n", dasm); 1.27 +/* 1.28 + size_t i = 0x80001a; 1.29 + size_t len; 1.30 + do { 1.31 + char dasm[512]; 1.32 + len = m68k_disassemble(dasm, i, M68K_CPU_TYPE_68010); 1.33 + printf("%06X: %s\n", i, dasm); 1.34 + i += len; 1.35 + } while (i < 0x8000ff); 1.36 +*/ 1.37 1.38 // set up SDL 1.39 + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) { 1.40 + printf("Could not initialise SDL: %s.\n", SDL_GetError()); 1.41 + return -1; 1.42 + } 1.43 1.44 - // emulation loop! 1.45 - // repeat: 1.46 - // m68k_execute() 1.47 - // m68k_set_irq() every 60ms 1.48 - int32_t dwTimerTickCounter, dwCpuCycles; 1.49 - const int32_t CLOCKS_PER_TIMER_TICK = 10e6/60; //< number of clocks per 60Hz timer tick 1.50 - 1.51 - // initialise emulation variables 1.52 - dwTimerTickCounter = CLOCKS_PER_TIMER_TICK; 1.53 + /*** 1.54 + * The 3B1 CPU runs at 10MHz, with DMA running at 1MHz and video refreshing at 1.55 + * around 60Hz (???), with a 60Hz periodic interrupt. 1.56 + */ 1.57 + const uint32_t TIMESLOT_FREQUENCY = 240; // Hz 1.58 + const uint32_t MILLISECS_PER_TIMESLOT = 1e3 / TIMESLOT_FREQUENCY; 1.59 + const uint32_t CLOCKS_PER_60HZ = (10e6 / 60); 1.60 + uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT; 1.61 + uint32_t clock_cycles = 0; 1.62 bool exitEmu = false; 1.63 for (;;) { 1.64 - dwCpuCycles = m68k_execute(10e6/60); 1.65 - dwTimerTickCounter -= dwCpuCycles; 1.66 + // Run the CPU for however many cycles we need to. CPU core clock is 1.67 + // 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or 1.68 + // 41667 cycles per timeslot. 1.69 + clock_cycles += m68k_execute(10e6/TIMESLOT_FREQUENCY); 1.70 + 1.71 + // TODO: run DMA here 1.72 1.73 - // check for timer tick expiry 1.74 - if (dwTimerTickCounter <= 0) { 1.75 - // TODO: Timer Tick IRQ 1.76 - 1.77 + // Is it time to run the 60Hz periodic interrupt yet? 1.78 + if (clock_cycles > CLOCKS_PER_60HZ) { 1.79 + // TODO: refresh screen 1.80 + // TODO: trigger periodic interrupt (if enabled) 1.81 + // decrement clock cycle counter, we've handled the intr. 1.82 + clock_cycles -= CLOCKS_PER_60HZ; 1.83 } 1.84 1.85 + printf("timeslot\n"); 1.86 + 1.87 + // make sure frame rate is equal to real time 1.88 + uint32_t now = SDL_GetTicks(); 1.89 + if (now < next_timeslot) { 1.90 + // timeslot finished early -- eat up some time 1.91 + SDL_Delay(next_timeslot - now); 1.92 + } else { 1.93 + // timeslot finished late -- skip ahead to gain time 1.94 + // TODO: if this happens a lot, we should let the user know 1.95 + // that their PC might not be fast enough... 1.96 + next_timeslot = now; 1.97 + } 1.98 + // advance to the next timeslot 1.99 + next_timeslot += MILLISECS_PER_TIMESLOT; 1.100 + 1.101 + // if we've been asked to exit the emulator, then do so. 1.102 if (exitEmu) break; 1.103 } 1.104 1.105 // shut down and exit 1.106 + SDL_Quit(); 1.107 1.108 return 0; 1.109 }