src/state.c

Tue, 21 May 2013 22:48:32 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Tue, 21 May 2013 22:48:32 +0100
branch
experimental_memory_mapper_v2
changeset 145
2d6de28c6e6c
parent 112
a392eb8f9806
permissions
-rw-r--r--

Code clean up

* Tighten optimisation and warning options to find more potential issues
* Remove unused variable in keyboard code
* Display error message if ROMs fail to load
* Fix format string bugs in WD2010

philpem@18 1 #define _STATE_C
philpem@18 2 #include <stddef.h>
philpem@18 3 #include <malloc.h>
philpem@18 4 #include <stdio.h>
philpem@52 5 #include "wd279x.h"
philpem@112 6 #include "wd2010.h"
philpem@80 7 #include "keyboard.h"
philpem@18 8 #include "state.h"
philpem@18 9
philpem@62 10 int state_init(size_t base_ram_size, size_t exp_ram_size)
philpem@18 11 {
philpem@18 12 // Free RAM if it's allocated
philpem@60 13 if (state.base_ram != NULL)
philpem@60 14 free(state.base_ram);
philpem@62 15 if (state.exp_ram != NULL)
philpem@62 16 free(state.exp_ram);
philpem@18 17
philpem@18 18 // Initialise hardware registers
philpem@18 19 state.romlmap = false;
philpem@75 20 state.idmarw = state.dmaen = state.dmaenb = false;
philpem@75 21 state.dma_count = state.dma_address = 0;
philpem@75 22 state.pie = 0;
philpem@101 23 state.ee = 0;
philpem@75 24 state.leds = 0;
philpem@75 25 state.genstat = 0; // FIXME: check this
philpem@75 26 state.bsr0 = state.bsr1 = 0; // FIXME: check this
philpem@97 27 state.timer_enabled = state.timer_asserted = false;
philpem@62 28 // Allocate Base RAM, making sure the user has specified a valid RAM amount first
philpem@62 29 // Basically: 512KiB minimum, 2MiB maximum, in increments of 512KiB.
philpem@62 30 if ((base_ram_size < 512*1024) || (base_ram_size > 2048*1024) || ((base_ram_size % (512*1024)) != 0))
philpem@18 31 return -1;
philpem@62 32 state.base_ram = malloc(base_ram_size);
philpem@60 33 if (state.base_ram == NULL)
philpem@18 34 return -2;
philpem@62 35 state.base_ram_size = base_ram_size;
philpem@62 36
philpem@62 37 // Now allocate expansion RAM
philpem@62 38 // The difference here is that we can have zero bytes of Expansion RAM; we're not limited to having a minimum of 512KiB.
philpem@62 39 if ((exp_ram_size > 2048*1024) || ((exp_ram_size % (512*1024)) != 0))
philpem@62 40 return -1;
philpem@62 41 state.exp_ram = malloc(exp_ram_size);
philpem@62 42 if (state.exp_ram == NULL)
philpem@62 43 return -2;
philpem@62 44 state.exp_ram_size = exp_ram_size;
philpem@18 45
philpem@18 46 // Load ROMs
philpem@18 47 FILE *r14c, *r15c;
philpem@18 48 r14c = fopen("roms/14c.bin", "rb");
philpem@55 49 if (r14c == NULL) {
philpem@55 50 fprintf(stderr, "[state] Error loading roms/14c.bin.\n");
philpem@55 51 return -3;
philpem@55 52 }
philpem@18 53 r15c = fopen("roms/15c.bin", "rb");
philpem@55 54 if (r15c == NULL) {
philpem@55 55 fprintf(stderr, "[state] Error loading roms/15c.bin.\n");
philpem@55 56 return -3;
philpem@55 57 }
philpem@18 58
philpem@18 59 // get ROM file size
philpem@18 60 fseek(r14c, 0, SEEK_END);
philpem@18 61 size_t romlen = ftell(r14c);
philpem@18 62 fseek(r14c, 0, SEEK_SET);
philpem@18 63 fseek(r15c, 0, SEEK_END);
philpem@18 64 size_t romlen2 = ftell(r15c);
philpem@18 65 fseek(r15c, 0, SEEK_SET);
philpem@55 66 if (romlen2 != romlen) {
philpem@55 67 fprintf(stderr, "[state] ROMs are not the same size!\n");
philpem@55 68 return -3;
philpem@55 69 }
philpem@55 70 if ((romlen + romlen2) > ROM_SIZE) {
philpem@55 71 fprintf(stderr, "[state] ROM files are too large!\n");
philpem@55 72 return -3;
philpem@55 73 }
philpem@18 74
philpem@18 75 // sanity checks completed; load the ROMs!
philpem@18 76 uint8_t *romdat1, *romdat2;
philpem@18 77 romdat1 = malloc(romlen);
philpem@18 78 romdat2 = malloc(romlen2);
philpem@145 79 if (fread(romdat1, 1, romlen, r15c) != romlen) {
philpem@145 80 fprintf(stderr, "[state] Error reading ROM 15C.\n");
philpem@145 81 return -3;
philpem@145 82 }
philpem@145 83 if (fread(romdat2, 1, romlen2, r14c) != romlen) {
philpem@145 84 fprintf(stderr, "[state] Error reading ROM 14C.\n");
philpem@145 85 return -3;
philpem@145 86 }
philpem@18 87
philpem@18 88 // convert the ROM data
philpem@18 89 for (size_t i=0; i<(romlen + romlen2); i+=2) {
philpem@18 90 state.rom[i+0] = romdat1[i/2];
philpem@18 91 state.rom[i+1] = romdat2[i/2];
philpem@18 92 }
philpem@18 93
philpem@18 94 // TODO: if ROM buffer not filled, repeat the ROM data we read until it is (wraparound emulation)
philpem@18 95
philpem@18 96 // free the data arrays and close the files
philpem@18 97 free(romdat1);
philpem@18 98 free(romdat2);
philpem@18 99 fclose(r14c);
philpem@18 100 fclose(r15c);
philpem@18 101
philpem@52 102 // Initialise the disc controller
philpem@52 103 wd2797_init(&state.fdc_ctx);
philpem@80 104 // Initialise the keyboard controller
philpem@80 105 keyboard_init(&state.kbd);
philpem@52 106
philpem@18 107 return 0;
philpem@18 108 }
philpem@18 109
philpem@18 110 void state_done()
philpem@18 111 {
philpem@60 112 if (state.base_ram != NULL) {
philpem@60 113 free(state.base_ram);
philpem@60 114 state.base_ram = NULL;
philpem@18 115 }
philpem@62 116
philpem@62 117 if (state.exp_ram != NULL) {
philpem@62 118 free(state.exp_ram);
philpem@62 119 state.exp_ram = NULL;
philpem@62 120 }
philpem@62 121
philpem@52 122 // Deinitialise the disc controller
philpem@52 123 wd2797_done(&state.fdc_ctx);
philpem@112 124 wd2010_done(&state.hdc_ctx);
philpem@18 125 }
philpem@18 126
philpem@18 127