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