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 --- 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