src/main.c

Thu, 02 Dec 2010 23:03:13 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 02 Dec 2010 23:03:13 +0000
changeset 40
239bc48590ba
parent 39
cab49f90c3b9
child 41
75887b42d7e5
permissions
-rw-r--r--

move memory access and mapping functions into memory.[ch]

This is to tidy up main.c...

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <stdint.h>
     4 #include <stdbool.h>
     5 #include <malloc.h>
     6 #include <string.h>
     8 #include "SDL.h"
    10 #include "musashi/m68k.h"
    11 #include "version.h"
    12 #include "state.h"
    13 #include "memory.h"
    15 void FAIL(char *err)
    16 {
    17 	state_done();
    18 	fprintf(stderr, "ERROR: %s\nExiting...\n", err);
    19 	exit(EXIT_FAILURE);
    20 }
    22 /****************************
    23  * blessed be thy main()...
    24  ****************************/
    26 int main(void)
    27 {
    28 	// copyright banner
    29 	printf("FreeBee: A Quick-and-Dirty AT&T 3B1 Emulator. Version %s, %s mode.\n", VER_FULLSTR, VER_BUILD_TYPE);
    30 	printf("Copyright (C) 2010 P. A. Pemberton. All rights reserved.\nLicensed under the Apache License Version 2.0.\n");
    31 	printf("Musashi M680x0 emulator engine developed by Karl Stenerud <kstenerud@gmail.com>\n");
    32 	printf("Built %s by %s@%s.\n", VER_COMPILE_DATETIME, VER_COMPILE_BY, VER_COMPILE_HOST);
    33 	printf("Compiler: %s\n", VER_COMPILER);
    34 	printf("CFLAGS: %s\n", VER_CFLAGS);
    35 	printf("\n");
    37 	// set up system state
    38 	// 512K of RAM
    39 	state_init(512*1024);
    41 	// set up musashi and reset the CPU
    42 	m68k_set_cpu_type(M68K_CPU_TYPE_68010);
    43 	m68k_pulse_reset();
    45 	// Set up SDL
    46 	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
    47 		printf("Could not initialise SDL: %s.\n", SDL_GetError());
    48 		exit(EXIT_FAILURE);
    49 	}
    51 	// Make sure SDL cleans up after itself
    52 	atexit(SDL_Quit);
    54 	// Set up the video display
    55 	SDL_Surface *screen = NULL;
    56 	if ((screen = SDL_SetVideoMode(720, 384, 8, SDL_SWSURFACE | SDL_ANYFORMAT)) == NULL) {
    57 		printf("Could not find a suitable video mode: %s.\n", SDL_GetError());
    58 		exit(EXIT_FAILURE);
    59 	}
    60 	printf("Set %dx%d at %d bits-per-pixel mode\n\n", screen->w, screen->h, screen->format->BitsPerPixel);
    61 	SDL_WM_SetCaption("FreeBee 3B1 emulator", "FreeBee");
    63 	/***
    64 	 * The 3B1 CPU runs at 10MHz, with DMA running at 1MHz and video refreshing at
    65 	 * around 60Hz (???), with a 60Hz periodic interrupt.
    66 	 */
    67 	const uint32_t TIMESLOT_FREQUENCY = 240;	// Hz
    68 	const uint32_t MILLISECS_PER_TIMESLOT = 1e3 / TIMESLOT_FREQUENCY;
    69 	const uint32_t CLOCKS_PER_60HZ = (10e6 / 60);
    70 	uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT;
    71 	uint32_t clock_cycles = 0;
    72 	bool exitEmu = false;
    73 	for (;;) {
    74 		// Run the CPU for however many cycles we need to. CPU core clock is
    75 		// 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or
    76 		// 41667 cycles per timeslot.
    77 		clock_cycles += m68k_execute(10e6/TIMESLOT_FREQUENCY);
    79 		// TODO: run DMA here
    81 		// Is it time to run the 60Hz periodic interrupt yet?
    82 		if (clock_cycles > CLOCKS_PER_60HZ) {
    83 			// TODO: refresh screen
    84 			// TODO: trigger periodic interrupt (if enabled)
    85 			// decrement clock cycle counter, we've handled the intr.
    86 			clock_cycles -= CLOCKS_PER_60HZ;
    87 		}
    89 		// make sure frame rate is equal to real time
    90 		uint32_t now = SDL_GetTicks();
    91 		if (now < next_timeslot) {
    92 			// timeslot finished early -- eat up some time
    93 			SDL_Delay(next_timeslot - now);
    94 		} else {
    95 			// timeslot finished late -- skip ahead to gain time
    96 			// TODO: if this happens a lot, we should let the user know
    97 			// that their PC might not be fast enough...
    98 			next_timeslot = now;
    99 		}
   100 		// advance to the next timeslot
   101 		next_timeslot += MILLISECS_PER_TIMESLOT;
   103 		// if we've been asked to exit the emulator, then do so.
   104 		if (exitEmu) break;
   105 	}
   107 	// shut down and exit
   108 	SDL_Quit();
   110 	return 0;
   111 }