Mon, 29 Nov 2010 00:20:40 +0000
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 }