src/main.c

Sun, 28 Nov 2010 20:52:53 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 28 Nov 2010 20:52:53 +0000
changeset 9
3e99497dca33
parent 8
e2dcbabc7e1c
child 10
dbf4ba9563c9
permissions
-rw-r--r--

fix memory read stuff, now need to deal with memory write

philpem@0 1 #include <stdio.h>
philpem@7 2 #include <stdlib.h>
philpem@4 3 #include <stdint.h>
philpem@7 4 #include <stdbool.h>
philpem@7 5 #include <malloc.h>
philpem@7 6 #include <string.h>
philpem@4 7 #include "musashi/m68k.h"
philpem@7 8 #include "version.h"
philpem@7 9
philpem@9 10 #define ROM_SIZE (32768/2)
philpem@7 11
philpem@7 12 void state_done(void);
philpem@7 13
philpem@7 14 void FAIL(char *err)
philpem@7 15 {
philpem@7 16 state_done();
philpem@7 17 fprintf(stderr, "ERROR: %s\nExiting...\n", err);
philpem@7 18 exit(EXIT_FAILURE);
philpem@7 19 }
philpem@7 20
philpem@7 21
philpem@7 22 struct {
philpem@7 23 // Boot PROM can be up to 32Kbytes total size
philpem@9 24 uint16_t rom[ROM_SIZE];
philpem@7 25
philpem@7 26 // Main system RAM
philpem@9 27 uint16_t *ram;
philpem@7 28 size_t ram_size; // number of RAM bytes allocated
philpem@7 29 uint32_t ram_addr_mask; // address mask
philpem@7 30
philpem@7 31 // GENERAL CONTROL REGISTER
philpem@7 32 bool romlmap;
philpem@7 33 } state;
philpem@7 34
philpem@7 35 int state_init()
philpem@7 36 {
philpem@7 37 // Free RAM if it's allocated
philpem@7 38 if (state.ram != NULL)
philpem@7 39 free(state.ram);
philpem@7 40
philpem@7 41 // Initialise hardware registers
philpem@7 42 state.romlmap = false;
philpem@7 43
philpem@7 44 // Allocate RAM
philpem@7 45 // TODO: make sure ram size selection is valid!
philpem@7 46 state.ram = malloc(state.ram_size);
philpem@7 47 if (state.ram == NULL)
philpem@7 48 return -1;
philpem@7 49 state.ram_addr_mask = state.ram_size - 1;
philpem@4 50
philpem@7 51 // Load ROMs
philpem@7 52 FILE *r14c, *r15c;
philpem@7 53 r14c = fopen("roms/14c.bin", "rb");
philpem@7 54 if (r14c == NULL) FAIL("unable to open roms/14c.bin");
philpem@7 55 r15c = fopen("roms/15c.bin", "rb");
philpem@7 56 if (r15c == NULL) FAIL("unable to open roms/15c.bin");
philpem@7 57
philpem@7 58 // get ROM file size
philpem@7 59 fseek(r14c, 0, SEEK_END);
philpem@7 60 size_t romlen = ftell(r14c);
philpem@7 61 fseek(r14c, 0, SEEK_SET);
philpem@7 62 fseek(r15c, 0, SEEK_END);
philpem@7 63 size_t romlen2 = ftell(r15c);
philpem@7 64 fseek(r15c, 0, SEEK_SET);
philpem@7 65 if (romlen2 != romlen) FAIL("ROMs are not the same size!");
philpem@7 66 if ((romlen / 4) > (ROM_SIZE / 2)) FAIL("ROM 14C is too big!");
philpem@7 67 if ((romlen2 / 4) > (ROM_SIZE / 2)) FAIL("ROM 15C is too big!");
philpem@7 68
philpem@7 69 // sanity checks completed; load the ROMs!
philpem@7 70 uint8_t *romdat1, *romdat2;
philpem@7 71 romdat1 = malloc(romlen);
philpem@7 72 romdat2 = malloc(romlen2);
philpem@7 73 fread(romdat1, 1, romlen, r15c);
philpem@7 74 fread(romdat2, 1, romlen2, r14c);
philpem@7 75
philpem@7 76 // convert the ROM data
philpem@9 77 for (size_t i=0; i<romlen; i++) {
philpem@9 78 state.rom[i] = ((romdat1[i] << 8) | (romdat2[i]));
philpem@7 79 }
philpem@7 80
philpem@7 81 // free the data arrays and close the files
philpem@7 82 free(romdat1);
philpem@7 83 free(romdat2);
philpem@7 84 fclose(r14c);
philpem@7 85 fclose(r15c);
philpem@7 86
philpem@7 87 return 0;
philpem@7 88 }
philpem@7 89
philpem@7 90 void state_done()
philpem@7 91 {
philpem@7 92 if (state.ram != NULL)
philpem@7 93 free(state.ram);
philpem@7 94 }
philpem@4 95
philpem@4 96 // read m68k memory
philpem@7 97 // TODO: refactor musashi to use stdint, and properly sized integers!
philpem@7 98 // TODO: find a way to make musashi use function pointers instead of hard coded callbacks, maybe use a context struct too
philpem@4 99 uint32_t m68k_read_memory_32(uint32_t address)
philpem@4 100 {
philpem@9 101 uint32_t data = 0xFFFFFFFF;
philpem@9 102
philpem@9 103 printf("RD32 %08X %d", address, state.romlmap);
philpem@9 104
philpem@7 105 // If ROMLMAP is set, force system to access ROM
philpem@7 106 if (!state.romlmap)
philpem@7 107 address |= 0x800000;
philpem@7 108
philpem@9 109 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 110 // ROM access
philpem@9 111 data = ((state.rom[(address & (ROM_SIZE-1)) / 2] << 16) | (state.rom[((address & (ROM_SIZE-1)) / 2)+1]));
philpem@7 112 } else if (address <= 0x3FFFFF) {
philpem@7 113 // RAM
philpem@9 114 data = state.ram[(address & state.ram_addr_mask) / 2];
philpem@7 115 }
philpem@9 116
philpem@9 117 printf(" ==> %04X\n", data);
philpem@9 118 return data;
philpem@4 119 }
philpem@4 120
philpem@4 121 uint32_t m68k_read_memory_16(uint32_t address)
philpem@4 122 {
philpem@9 123 uint16_t data = 0xFFFF;
philpem@9 124
philpem@9 125 printf("RD16 %08X %d", address, state.romlmap);
philpem@9 126
philpem@9 127 // If ROMLMAP is set, force system to access ROM
philpem@9 128 if (!state.romlmap)
philpem@9 129 address |= 0x800000;
philpem@9 130
philpem@9 131 data = (m68k_read_memory_32(address) >> 16) & 0xFFFF;
philpem@9 132
philpem@9 133 printf(" ==> %04X\n", data);
philpem@9 134 return data;
philpem@4 135 }
philpem@4 136
philpem@4 137 uint32_t m68k_read_memory_8(uint32_t address)
philpem@4 138 {
philpem@9 139 uint8_t data = 0xFF;
philpem@9 140
philpem@9 141 printf("RD 8 %08X %d ", address, state.romlmap);
philpem@9 142
philpem@7 143 // If ROMLMAP is set, force system to access ROM
philpem@7 144 if (!state.romlmap)
philpem@7 145 address |= 0x800000;
philpem@7 146
philpem@9 147 data = m68k_read_memory_32(address) & 0xFF;
philpem@9 148
philpem@9 149 printf("==> %02X\n", data);
philpem@9 150 return data;
philpem@4 151 }
philpem@4 152
philpem@4 153 // write m68k memory
philpem@4 154 void m68k_write_memory_32(uint32_t address, uint32_t value)
philpem@4 155 {
philpem@7 156 // If ROMLMAP is set, force system to access ROM
philpem@7 157 if (!state.romlmap)
philpem@7 158 address |= 0x800000;
philpem@7 159
philpem@9 160 printf("WR32 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 161
philpem@9 162 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 163 // ROM access
philpem@7 164 // TODO: bus error here? can't write to rom!
philpem@7 165 } else if (address <= 0x3FFFFF) {
philpem@7 166 // RAM
philpem@9 167 state.ram[(address & state.ram_addr_mask) / 2] = (value >> 16);
philpem@9 168 state.ram[((address & state.ram_addr_mask) / 2)+1] = value & 0xffff;
philpem@9 169 } else {
philpem@9 170 switch (address) {
philpem@9 171 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000);
philpem@9 172 }
philpem@7 173 }
philpem@4 174 }
philpem@4 175
philpem@4 176 void m68k_write_memory_16(uint32_t address, uint32_t value)
philpem@4 177 {
philpem@7 178 // If ROMLMAP is set, force system to access ROM
philpem@7 179 if (!state.romlmap)
philpem@7 180 address |= 0x800000;
philpem@7 181
philpem@9 182 printf("WR16 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 183
philpem@9 184 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 185 // ROM access
philpem@7 186 // TODO: bus error here? can't write to rom!
philpem@7 187 } else if (address <= 0x3FFFFF) {
philpem@7 188 // RAM
philpem@9 189 state.ram[(address & state.ram_addr_mask) / 2] = value & 0xFFFF;
philpem@9 190 } else {
philpem@9 191 switch (address) {
philpem@9 192 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000);
philpem@9 193 }
philpem@7 194 }
philpem@4 195 }
philpem@4 196
philpem@4 197 void m68k_write_memory_8(uint32_t address, uint32_t value)
philpem@4 198 {
philpem@7 199 // If ROMLMAP is set, force system to access ROM
philpem@7 200 if (!state.romlmap)
philpem@7 201 address |= 0x800000;
philpem@7 202
philpem@9 203 printf("WR 8 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 204
philpem@9 205 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 206 // ROM access
philpem@7 207 // TODO: bus error here? can't write to rom!
philpem@7 208 } else if (address <= 0x3FFFFF) {
philpem@7 209 // RAM
philpem@7 210 switch (address & 3) {
philpem@9 211 // FIXME
philpem@7 212 case 3: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFFFFFF00) | (value & 0xFF);
philpem@7 213 case 2: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFFFF00FF) | ((value & 0xFF) << 8);
philpem@7 214 case 1: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFF00FFFF) | ((value & 0xFF) << 16);
philpem@7 215 case 0: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0x00FFFFFF) | ((value & 0xFF) << 24);
philpem@7 216 }
philpem@9 217 } else {
philpem@9 218 switch (address) {
philpem@9 219 case 0xE43000: state.romlmap = ((value & 0x80) == 0x80);
philpem@9 220 }
philpem@7 221 }
philpem@4 222 }
philpem@4 223
philpem@9 224 uint32_t m68k_read_disassembler_32(uint32_t addr) { return m68k_read_memory_32(addr); }
philpem@9 225 uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); }
philpem@9 226 uint32_t m68k_read_disassembler_8 (uint32_t addr) { return m68k_read_memory_8 (addr); }
philpem@9 227
philpem@0 228 int main(void)
philpem@0 229 {
philpem@7 230 // copyright banner
philpem@7 231 printf("FreeBee: A Quick-and-Dirty AT&T 3B1 Emulator\n");
philpem@7 232 printf("Copyright (C) 2010 P. A. Pemberton.\n");
philpem@7 233 printf("Musashi M680x0 emulator engine developed by Karl Stenerud <kstenerud@gmail.com>\n");
philpem@7 234
philpem@7 235 // set up system state
philpem@7 236 // 512K of RAM
philpem@7 237 state.ram_size = 512*1024;
philpem@7 238 state_init();
philpem@7 239
philpem@7 240 // set up musashi
philpem@7 241 m68k_set_cpu_type(M68K_CPU_TYPE_68010);
philpem@7 242 m68k_pulse_reset();
philpem@7 243
philpem@9 244 char dasm[512];
philpem@9 245 m68k_disassemble(dasm, 0x80001a, M68K_CPU_TYPE_68010);
philpem@9 246 printf("%s\n", dasm);
philpem@9 247
philpem@7 248 // set up SDL
philpem@7 249
philpem@7 250 // emulation loop!
philpem@7 251 // repeat:
philpem@7 252 // m68k_execute()
philpem@7 253 // m68k_set_irq() every 60ms
philpem@8 254 printf("ran for %d cycles\n", m68k_execute(100000));
philpem@7 255
philpem@7 256 // shut down and exit
philpem@7 257
philpem@0 258 return 0;
philpem@0 259 }