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