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]

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