Tue, 15 Jan 2013 17:02:56 +0000
Implement m68k_read_disassembler_* properly
The previous implementations of m68k_read_disassembler are unsuitable due to
interactions with the memory mapper. A read from memory by the DASM should not
mutate system state.
So we modify the m68k_read_disassembler_{8,16,32} functions to do the memory
mapping themselves without causing page faults (bus error exception) or
updating the page flag bits (which could really upset the kernel).
Now all we need is a debugger/disassembler...
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 fread(romdat1, 1, romlen, r15c);
80 fread(romdat2, 1, romlen2, r14c);
82 // convert the ROM data
83 for (size_t i=0; i<(romlen + romlen2); i+=2) {
84 state.rom[i+0] = romdat1[i/2];
85 state.rom[i+1] = romdat2[i/2];
86 }
88 // TODO: if ROM buffer not filled, repeat the ROM data we read until it is (wraparound emulation)
90 // free the data arrays and close the files
91 free(romdat1);
92 free(romdat2);
93 fclose(r14c);
94 fclose(r15c);
96 // Initialise the disc controller
97 wd2797_init(&state.fdc_ctx);
98 // Initialise the keyboard controller
99 keyboard_init(&state.kbd);
101 return 0;
102 }
104 void state_done()
105 {
106 if (state.base_ram != NULL) {
107 free(state.base_ram);
108 state.base_ram = NULL;
109 }
111 if (state.exp_ram != NULL) {
112 free(state.exp_ram);
113 state.exp_ram = NULL;
114 }
116 // Deinitialise the disc controller
117 wd2797_done(&state.fdc_ctx);
118 wd2010_done(&state.hdc_ctx);
119 }