split state handling into state.[ch]

Mon, 29 Nov 2010 00:20:40 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 29 Nov 2010 00:20:40 +0000
changeset 18
320dc6206f52
parent 17
138cb2576dbc
child 19
ea417ac1d83a

split state handling into state.[ch]

Makefile file | annotate | diff | revisions
src/main.c file | annotate | diff | revisions
src/state.c file | annotate | diff | revisions
src/state.h file | annotate | diff | revisions
     1.1 --- a/Makefile	Sun Nov 28 23:29:00 2010 +0000
     1.2 +++ b/Makefile	Mon Nov 29 00:20:40 2010 +0000
     1.3 @@ -118,7 +118,8 @@
     1.4  TARGET		=	freebee
     1.5  
     1.6  # source files that produce object files
     1.7 -SRC			=	main.c musashi/m68kcpu.c musashi/m68kdasm.c musashi/m68kops.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
     1.8 +SRC			=	main.c state.c
     1.9 +SRC			+=	musashi/m68kcpu.c musashi/m68kdasm.c musashi/m68kops.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
    1.10  
    1.11  # source type - either "c" or "cpp" (C or C++)
    1.12  SRC_TYPE	=	c
     2.1 --- a/src/main.c	Sun Nov 28 23:29:00 2010 +0000
     2.2 +++ b/src/main.c	Mon Nov 29 00:20:40 2010 +0000
     2.3 @@ -4,10 +4,11 @@
     2.4  #include <stdbool.h>
     2.5  #include <malloc.h>
     2.6  #include <string.h>
     2.7 +
     2.8  #include "musashi/m68k.h"
     2.9 +
    2.10  #include "version.h"
    2.11 -
    2.12 -void state_done(void);
    2.13 +#include "state.h"
    2.14  
    2.15  void FAIL(char *err)
    2.16  {
    2.17 @@ -16,85 +17,6 @@
    2.18  	exit(EXIT_FAILURE);
    2.19  }
    2.20  
    2.21 -// Maximum size of the Boot PROMs. Must be a binary power of two.
    2.22 -#define ROM_SIZE 32768
    2.23 -
    2.24 -struct {
    2.25 -	// Boot PROM can be up to 32Kbytes total size
    2.26 -	uint8_t		rom[ROM_SIZE];
    2.27 -
    2.28 -	// Main system RAM
    2.29 -	uint8_t		*ram;
    2.30 -	size_t		ram_size;			// number of RAM bytes allocated
    2.31 -
    2.32 -	// GENERAL CONTROL REGISTER
    2.33 -	bool		romlmap;
    2.34 -} state;
    2.35 -
    2.36 -int state_init()
    2.37 -{
    2.38 -	// Free RAM if it's allocated
    2.39 -	if (state.ram != NULL)
    2.40 -		free(state.ram);
    2.41 -
    2.42 -	// Initialise hardware registers
    2.43 -	state.romlmap = false;
    2.44 -
    2.45 -	// Allocate RAM, making sure the user has specified a valid RAM amount first
    2.46 -	// Basically: 512KiB minimum, 4MiB maximum, in increments of 512KiB.
    2.47 -	if ((state.ram_size < 512*1024) || ((state.ram_size % (512*1024)) != 0))
    2.48 -		return -1;
    2.49 -	state.ram = malloc(state.ram_size);
    2.50 -	if (state.ram == NULL)
    2.51 -		return -2;
    2.52 -
    2.53 -	// Load ROMs
    2.54 -	FILE *r14c, *r15c;
    2.55 -	r14c = fopen("roms/14c.bin", "rb");
    2.56 -	if (r14c == NULL) FAIL("unable to open roms/14c.bin");
    2.57 -	r15c = fopen("roms/15c.bin", "rb");
    2.58 -	if (r15c == NULL) FAIL("unable to open roms/15c.bin");
    2.59 -
    2.60 -	// get ROM file size
    2.61 -	fseek(r14c, 0, SEEK_END);
    2.62 -	size_t romlen = ftell(r14c);
    2.63 -	fseek(r14c, 0, SEEK_SET);
    2.64 -	fseek(r15c, 0, SEEK_END);
    2.65 -	size_t romlen2 = ftell(r15c);
    2.66 -	fseek(r15c, 0, SEEK_SET);
    2.67 -	if (romlen2 != romlen) FAIL("ROMs are not the same size!");
    2.68 -	if ((romlen + romlen2) > ROM_SIZE) FAIL("ROMs are too large to fit in memory!");
    2.69 -
    2.70 -	// sanity checks completed; load the ROMs!
    2.71 -	uint8_t *romdat1, *romdat2;
    2.72 -	romdat1 = malloc(romlen);
    2.73 -	romdat2 = malloc(romlen2);
    2.74 -	fread(romdat1, 1, romlen, r15c);
    2.75 -	fread(romdat2, 1, romlen2, r14c);
    2.76 -
    2.77 -	// convert the ROM data
    2.78 -	for (size_t i=0; i<(romlen + romlen2); i+=2) {
    2.79 -		state.rom[i+0] = romdat1[i/2];
    2.80 -		state.rom[i+1] = romdat2[i/2];
    2.81 -	}
    2.82 -
    2.83 -	// TODO: if ROM buffer not filled, repeat the ROM data we read until it is (wraparound emulation)
    2.84 -
    2.85 -	// free the data arrays and close the files
    2.86 -	free(romdat1);
    2.87 -	free(romdat2);
    2.88 -	fclose(r14c);
    2.89 -	fclose(r15c);
    2.90 -
    2.91 -	return 0;
    2.92 -}
    2.93 -
    2.94 -void state_done()
    2.95 -{
    2.96 -	if (state.ram != NULL)
    2.97 -		free(state.ram);
    2.98 -}
    2.99 -
   2.100  // read m68k memory
   2.101  uint32_t m68k_read_memory_32(uint32_t address)
   2.102  {
   2.103 @@ -255,8 +177,7 @@
   2.104  
   2.105  	// set up system state
   2.106  	// 512K of RAM
   2.107 -	state.ram_size = 512*1024;
   2.108 -	state_init();
   2.109 +	state_init(512*1024);
   2.110  
   2.111  	// set up musashi
   2.112  	m68k_set_cpu_type(M68K_CPU_TYPE_68010);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/state.c	Mon Nov 29 00:20:40 2010 +0000
     3.3 @@ -0,0 +1,74 @@
     3.4 +#define _STATE_C
     3.5 +#include <stddef.h>
     3.6 +#include <malloc.h>
     3.7 +#include <stdio.h>
     3.8 +#include "state.h"
     3.9 +
    3.10 +int state_init(size_t ramsize)
    3.11 +{
    3.12 +	// Free RAM if it's allocated
    3.13 +	if (state.ram != NULL)
    3.14 +		free(state.ram);
    3.15 +
    3.16 +	// Initialise hardware registers
    3.17 +	state.romlmap = false;
    3.18 +
    3.19 +	// Allocate RAM, making sure the user has specified a valid RAM amount first
    3.20 +	// Basically: 512KiB minimum, 4MiB maximum, in increments of 512KiB.
    3.21 +	if ((ramsize < 512*1024) || ((ramsize % (512*1024)) != 0))
    3.22 +		return -1;
    3.23 +	state.ram = malloc(state.ram_size);
    3.24 +	if (state.ram == NULL)
    3.25 +		return -2;
    3.26 +	state.ram_size = ramsize;
    3.27 +
    3.28 +	// Load ROMs
    3.29 +	FILE *r14c, *r15c;
    3.30 +	r14c = fopen("roms/14c.bin", "rb");
    3.31 +//	if (r14c == NULL) FAIL("unable to open roms/14c.bin");
    3.32 +	r15c = fopen("roms/15c.bin", "rb");
    3.33 +//	if (r15c == NULL) FAIL("unable to open roms/15c.bin");
    3.34 +
    3.35 +	// get ROM file size
    3.36 +	fseek(r14c, 0, SEEK_END);
    3.37 +	size_t romlen = ftell(r14c);
    3.38 +	fseek(r14c, 0, SEEK_SET);
    3.39 +	fseek(r15c, 0, SEEK_END);
    3.40 +	size_t romlen2 = ftell(r15c);
    3.41 +	fseek(r15c, 0, SEEK_SET);
    3.42 +//	if (romlen2 != romlen) FAIL("ROMs are not the same size!");
    3.43 +//	if ((romlen + romlen2) > ROM_SIZE) FAIL("ROMs are too large to fit in memory!");
    3.44 +
    3.45 +	// sanity checks completed; load the ROMs!
    3.46 +	uint8_t *romdat1, *romdat2;
    3.47 +	romdat1 = malloc(romlen);
    3.48 +	romdat2 = malloc(romlen2);
    3.49 +	fread(romdat1, 1, romlen, r15c);
    3.50 +	fread(romdat2, 1, romlen2, r14c);
    3.51 +
    3.52 +	// convert the ROM data
    3.53 +	for (size_t i=0; i<(romlen + romlen2); i+=2) {
    3.54 +		state.rom[i+0] = romdat1[i/2];
    3.55 +		state.rom[i+1] = romdat2[i/2];
    3.56 +	}
    3.57 +
    3.58 +	// TODO: if ROM buffer not filled, repeat the ROM data we read until it is (wraparound emulation)
    3.59 +
    3.60 +	// free the data arrays and close the files
    3.61 +	free(romdat1);
    3.62 +	free(romdat2);
    3.63 +	fclose(r14c);
    3.64 +	fclose(r15c);
    3.65 +
    3.66 +	return 0;
    3.67 +}
    3.68 +
    3.69 +void state_done()
    3.70 +{
    3.71 +	if (state.ram != NULL) {
    3.72 +		free(state.ram);
    3.73 +		state.ram = NULL;
    3.74 +	}
    3.75 +}
    3.76 +
    3.77 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/state.h	Mon Nov 29 00:20:40 2010 +0000
     4.3 @@ -0,0 +1,55 @@
     4.4 +#ifndef _STATE_H
     4.5 +#define _STATE_H
     4.6 +
     4.7 +#include <stddef.h>
     4.8 +#include <stdint.h>
     4.9 +#include <stdbool.h>
    4.10 +
    4.11 +// Maximum size of the Boot PROMs. Must be a binary power of two.
    4.12 +#define ROM_SIZE 32768
    4.13 +
    4.14 +/**
    4.15 + * @brief Emulator state storage
    4.16 + *
    4.17 + * This structure stores the internal state of the emulator.
    4.18 + */
    4.19 +typedef struct {
    4.20 +	// Boot PROM can be up to 32Kbytes total size
    4.21 +	uint8_t		rom[ROM_SIZE];		///< Boot PROM data buffer
    4.22 +
    4.23 +	// Main system RAM
    4.24 +	uint8_t		*ram;				///< RAM data buffer
    4.25 +	size_t		ram_size;			///< Size of RAM buffer in bytes
    4.26 +
    4.27 +	// GENERAL CONTROL REGISTER
    4.28 +	/// GENCON.ROMLMAP -- false ORs the address with 0x800000, forcing the
    4.29 +	/// 68010 to access ROM instead of RAM when booting. TRM page 2-36.
    4.30 +	bool		romlmap;			
    4.31 +} S_state;
    4.32 +
    4.33 +// Global emulator state. Yes, I know global variables are evil, please don't
    4.34 +// email me and lecture me about it.  -philpem
    4.35 +#ifndef _STATE_C
    4.36 +extern S_state state;
    4.37 +#else
    4.38 +S_state state;
    4.39 +#endif
    4.40 +
    4.41 +/**
    4.42 + * @brief	Initialise system state
    4.43 + *
    4.44 + * @param	ramsize		RAM size in bytes -- must be a multiple of 512KiB, min 512KiB, max 4MiB.
    4.45 + *
    4.46 + * Initialises the emulator's internal state.
    4.47 + */
    4.48 +int state_init(size_t ramsize);
    4.49 +
    4.50 +/**
    4.51 + * @brief Deinitialise system state
    4.52 + *
    4.53 + * Deinitialises the saved state, and frees all memory. Call this function
    4.54 + * before exiting your program to avoid memory leaks.
    4.55 + */
    4.56 +void state_done();
    4.57 +
    4.58 +#endif