src/state.c

Fri, 12 Apr 2013 16:26:25 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 12 Apr 2013 16:26:25 +0100
branch
experimental_memory_mapper_v2
changeset 144
609707511166
parent 112
a392eb8f9806
child 138
d744db15cdf7
permissions
-rw-r--r--

Don't set PS1 if there is a level-7 interrupt or bus error

PS1 should only be set if the page was originally present (PS1 or PS0 set). If
PS0 and PS1 are clear (page not present) then do NOT set PS1.

Once again the TRM is blatantly and spectacularly wrong...

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@18 79 fread(romdat1, 1, romlen, r15c);
philpem@18 80 fread(romdat2, 1, romlen2, r14c);
philpem@18 81
philpem@18 82 // convert the ROM data
philpem@18 83 for (size_t i=0; i<(romlen + romlen2); i+=2) {
philpem@18 84 state.rom[i+0] = romdat1[i/2];
philpem@18 85 state.rom[i+1] = romdat2[i/2];
philpem@18 86 }
philpem@18 87
philpem@18 88 // TODO: if ROM buffer not filled, repeat the ROM data we read until it is (wraparound emulation)
philpem@18 89
philpem@18 90 // free the data arrays and close the files
philpem@18 91 free(romdat1);
philpem@18 92 free(romdat2);
philpem@18 93 fclose(r14c);
philpem@18 94 fclose(r15c);
philpem@18 95
philpem@52 96 // Initialise the disc controller
philpem@52 97 wd2797_init(&state.fdc_ctx);
philpem@80 98 // Initialise the keyboard controller
philpem@80 99 keyboard_init(&state.kbd);
philpem@52 100
philpem@18 101 return 0;
philpem@18 102 }
philpem@18 103
philpem@18 104 void state_done()
philpem@18 105 {
philpem@60 106 if (state.base_ram != NULL) {
philpem@60 107 free(state.base_ram);
philpem@60 108 state.base_ram = NULL;
philpem@18 109 }
philpem@62 110
philpem@62 111 if (state.exp_ram != NULL) {
philpem@62 112 free(state.exp_ram);
philpem@62 113 state.exp_ram = NULL;
philpem@62 114 }
philpem@62 115
philpem@52 116 // Deinitialise the disc controller
philpem@52 117 wd2797_done(&state.fdc_ctx);
philpem@112 118 wd2010_done(&state.hdc_ctx);
philpem@18 119 }
philpem@18 120
philpem@18 121