src/main.c

Mon, 29 Nov 2010 00:20:40 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 29 Nov 2010 00:20:40 +0000
changeset 18
320dc6206f52
parent 17
138cb2576dbc
child 20
bea459bc22a8
permissions
-rw-r--r--

split state handling into state.[ch]

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@18 7
philpem@4 8 #include "musashi/m68k.h"
philpem@18 9
philpem@7 10 #include "version.h"
philpem@18 11 #include "state.h"
philpem@7 12
philpem@7 13 void FAIL(char *err)
philpem@7 14 {
philpem@7 15 state_done();
philpem@7 16 fprintf(stderr, "ERROR: %s\nExiting...\n", err);
philpem@7 17 exit(EXIT_FAILURE);
philpem@7 18 }
philpem@7 19
philpem@4 20 // read m68k memory
philpem@4 21 uint32_t m68k_read_memory_32(uint32_t address)
philpem@4 22 {
philpem@9 23 uint32_t data = 0xFFFFFFFF;
philpem@9 24
philpem@9 25 printf("RD32 %08X %d", address, state.romlmap);
philpem@9 26
philpem@7 27 // If ROMLMAP is set, force system to access ROM
philpem@7 28 if (!state.romlmap)
philpem@7 29 address |= 0x800000;
philpem@7 30
philpem@9 31 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 32 // ROM access
philpem@10 33 data = (((uint32_t)state.rom[(address + 0) & (ROM_SIZE - 1)] << 24) |
philpem@10 34 ((uint32_t)state.rom[(address + 1) & (ROM_SIZE - 1)] << 16) |
philpem@10 35 ((uint32_t)state.rom[(address + 2) & (ROM_SIZE - 1)] << 8) |
philpem@10 36 ((uint32_t)state.rom[(address + 3) & (ROM_SIZE - 1)]));
philpem@10 37 } else if (address < state.ram_size - 1) {
philpem@7 38 // RAM
philpem@10 39 data = (((uint32_t)state.ram[address + 0] << 24) |
philpem@10 40 ((uint32_t)state.ram[address + 1] << 16) |
philpem@10 41 ((uint32_t)state.ram[address + 2] << 8) |
philpem@10 42 ((uint32_t)state.ram[address + 3]));
philpem@7 43 }
philpem@9 44
philpem@10 45 printf(" ==> %08X\n", data);
philpem@9 46 return data;
philpem@4 47 }
philpem@4 48
philpem@4 49 uint32_t m68k_read_memory_16(uint32_t address)
philpem@4 50 {
philpem@9 51 uint16_t data = 0xFFFF;
philpem@9 52
philpem@9 53 printf("RD16 %08X %d", address, state.romlmap);
philpem@9 54
philpem@9 55 // If ROMLMAP is set, force system to access ROM
philpem@9 56 if (!state.romlmap)
philpem@9 57 address |= 0x800000;
philpem@9 58
philpem@10 59 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@10 60 // ROM access
philpem@10 61 data = ((state.rom[(address + 0) & (ROM_SIZE - 1)] << 8) |
philpem@10 62 (state.rom[(address + 1) & (ROM_SIZE - 1)]));
philpem@10 63 } else if (address < state.ram_size - 1) {
philpem@10 64 // RAM
philpem@10 65 data = ((state.ram[address + 0] << 8) |
philpem@10 66 (state.ram[address + 1]));
philpem@10 67 }
philpem@9 68
philpem@9 69 printf(" ==> %04X\n", data);
philpem@9 70 return data;
philpem@4 71 }
philpem@4 72
philpem@4 73 uint32_t m68k_read_memory_8(uint32_t address)
philpem@4 74 {
philpem@9 75 uint8_t data = 0xFF;
philpem@9 76
philpem@9 77 printf("RD 8 %08X %d ", address, state.romlmap);
philpem@9 78
philpem@7 79 // If ROMLMAP is set, force system to access ROM
philpem@7 80 if (!state.romlmap)
philpem@7 81 address |= 0x800000;
philpem@7 82
philpem@10 83 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@10 84 // ROM access
philpem@10 85 data = state.rom[(address + 0) & (ROM_SIZE - 1)];
philpem@10 86 } else if (address < state.ram_size) {
philpem@10 87 // RAM access
philpem@10 88 data = state.ram[address + 0];
philpem@10 89 }
philpem@9 90
philpem@9 91 printf("==> %02X\n", data);
philpem@9 92 return data;
philpem@4 93 }
philpem@4 94
philpem@4 95 // write m68k memory
philpem@4 96 void m68k_write_memory_32(uint32_t address, uint32_t value)
philpem@4 97 {
philpem@7 98 // If ROMLMAP is set, force system to access ROM
philpem@7 99 if (!state.romlmap)
philpem@7 100 address |= 0x800000;
philpem@7 101
philpem@9 102 printf("WR32 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 103
philpem@9 104 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 105 // ROM access
philpem@7 106 // TODO: bus error here? can't write to rom!
philpem@10 107 } else if (address < state.ram_size) {
philpem@10 108 // RAM access
philpem@10 109 state.ram[address + 0] = (value >> 24) & 0xff;
philpem@10 110 state.ram[address + 1] = (value >> 16) & 0xff;
philpem@10 111 state.ram[address + 2] = (value >> 8) & 0xff;
philpem@10 112 state.ram[address + 3] = value & 0xff;
philpem@9 113 } else {
philpem@9 114 switch (address) {
philpem@9 115 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000);
philpem@9 116 }
philpem@7 117 }
philpem@4 118 }
philpem@4 119
philpem@4 120 void m68k_write_memory_16(uint32_t address, uint32_t value)
philpem@4 121 {
philpem@7 122 // If ROMLMAP is set, force system to access ROM
philpem@7 123 if (!state.romlmap)
philpem@7 124 address |= 0x800000;
philpem@7 125
philpem@9 126 printf("WR16 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 127
philpem@9 128 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 129 // ROM access
philpem@7 130 // TODO: bus error here? can't write to rom!
philpem@10 131 } else if (address < state.ram_size) {
philpem@10 132 // RAM access
philpem@10 133 state.ram[address + 0] = (value >> 8) & 0xff;
philpem@10 134 state.ram[address + 1] = value & 0xff;
philpem@9 135 } else {
philpem@9 136 switch (address) {
philpem@9 137 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000);
philpem@9 138 }
philpem@7 139 }
philpem@4 140 }
philpem@4 141
philpem@4 142 void m68k_write_memory_8(uint32_t address, uint32_t value)
philpem@4 143 {
philpem@7 144 // If ROMLMAP is set, force system to access ROM
philpem@7 145 if (!state.romlmap)
philpem@7 146 address |= 0x800000;
philpem@7 147
philpem@9 148 printf("WR 8 %08X %d %02X\n", address, state.romlmap, value);
philpem@9 149
philpem@9 150 if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
philpem@7 151 // ROM access
philpem@7 152 // TODO: bus error here? can't write to rom!
philpem@10 153 } else if (address < state.ram_size) {
philpem@10 154 state.ram[address] = value & 0xff;
philpem@9 155 } else {
philpem@9 156 switch (address) {
philpem@9 157 case 0xE43000: state.romlmap = ((value & 0x80) == 0x80);
philpem@9 158 }
philpem@7 159 }
philpem@4 160 }
philpem@4 161
philpem@10 162 // for the disassembler
philpem@9 163 uint32_t m68k_read_disassembler_32(uint32_t addr) { return m68k_read_memory_32(addr); }
philpem@9 164 uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); }
philpem@9 165 uint32_t m68k_read_disassembler_8 (uint32_t addr) { return m68k_read_memory_8 (addr); }
philpem@9 166
philpem@0 167 int main(void)
philpem@0 168 {
philpem@7 169 // copyright banner
philpem@16 170 printf("FreeBee: A Quick-and-Dirty AT&T 3B1 Emulator. Version %s, %s mode.\n", VER_FULLSTR, VER_BUILD_TYPE);
philpem@17 171 printf("Copyright (C) 2010 P. A. Pemberton. All rights reserved.\nLicensed under the Apache License Version 2.0.\n");
philpem@17 172 printf("Musashi M680x0 emulator engine developed by Karl Stenerud <kstenerud@gmail.com>\n");
philpem@16 173 printf("Built %s by %s@%s.\n", VER_COMPILE_DATETIME, VER_COMPILE_BY, VER_COMPILE_HOST);
philpem@16 174 printf("Compiler: %s\n", VER_COMPILER);
philpem@16 175 printf("CFLAGS: %s\n", VER_CFLAGS);
philpem@17 176 printf("\n");
philpem@7 177
philpem@7 178 // set up system state
philpem@7 179 // 512K of RAM
philpem@18 180 state_init(512*1024);
philpem@7 181
philpem@7 182 // set up musashi
philpem@7 183 m68k_set_cpu_type(M68K_CPU_TYPE_68010);
philpem@7 184 m68k_pulse_reset();
philpem@7 185
philpem@9 186 char dasm[512];
philpem@9 187 m68k_disassemble(dasm, 0x80001a, M68K_CPU_TYPE_68010);
philpem@9 188 printf("%s\n", dasm);
philpem@9 189
philpem@7 190 // set up SDL
philpem@7 191
philpem@7 192 // emulation loop!
philpem@7 193 // repeat:
philpem@7 194 // m68k_execute()
philpem@7 195 // m68k_set_irq() every 60ms
philpem@16 196 int32_t dwTimerTickCounter, dwCpuCycles;
philpem@16 197 const int32_t CLOCKS_PER_TIMER_TICK = 10e6/60; //< number of clocks per 60Hz timer tick
philpem@16 198
philpem@16 199 // initialise emulation variables
philpem@16 200 dwTimerTickCounter = CLOCKS_PER_TIMER_TICK;
philpem@16 201 bool exitEmu = false;
philpem@16 202 for (;;) {
philpem@16 203 dwCpuCycles = m68k_execute(10e6/60);
philpem@16 204 dwTimerTickCounter -= dwCpuCycles;
philpem@16 205
philpem@16 206 // check for timer tick expiry
philpem@16 207 if (dwTimerTickCounter <= 0) {
philpem@16 208 // TODO: Timer Tick IRQ
philpem@16 209
philpem@16 210 }
philpem@16 211
philpem@16 212 if (exitEmu) break;
philpem@16 213 }
philpem@7 214
philpem@7 215 // shut down and exit
philpem@7 216
philpem@0 217 return 0;
philpem@0 218 }