Mon, 29 Nov 2010 00:20:40 +0000
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