8 #include "simh/PDP11/pdp11_defs.h"
9 #include "simh/PDP11/pdp11_cpumod.h"
11 extern int32 REGFILE[6][2]; /* R0-R5, two sets */
12 extern int32 STACKFILE[4]; /* SP, four modes */
13 extern int32 saved_PC; /* program counter */
14 extern int32 PSW; /* PSW */
15 extern int32 last_pa; /* pa from ReadMW/ReadMB */
16 t_stat cpu_reset (DEVICE *dptr);
18 #include "cpu_pdp11.h"
21 #define EXCEPTION_TRAP_BASE 0x20
26 #define MEM_SIZE 0x10000
27 #if __BYTE_ORDER == __BIG_ENDIAN
28 #define MEM_SIZE_M1 (MEM_SIZE - 1)
29 #define MEM_SIZE_M2 (MEM_SIZE - 2)
36 uint16_t w[MEM_SIZE >> 1];
39 int load_ihx(char *name) {
40 FILE *fp = fopen(name, "r");
46 int base = 0, entry_point = 0;
49 while (fgets(line, 0x100, fp)) {
50 for (char *p = line; *p; ++p)
57 fprintf(stderr, "garbage after EOF record: %s\n", line);
62 fprintf(stderr, "require colon: %s\n", line);
68 for (len = 0; len < 0x7f; ++len) {
69 char *p = line + 1 + len * 2;
80 buf[len] = (uint8_t)strtol(p, &q, 16);
83 fprintf(stderr, "not hex byte: %s\n", p);
89 fprintf(stderr, "empty line: %s\n", line);
94 for (int i = 0; i < len; ++i)
97 checksum -= buf[len - 1];
100 "checksum %03o, should be %03o\n",
109 fprintf(stderr, "incorrect length: %s\n", line);
113 int addr = (buf[1] << 8) | buf[2], end_addr;
117 end_addr = addr + len;
118 if (end_addr < addr || end_addr > MEM_SIZE) {
119 fprintf(stderr, "invalid load range: [0x%x, 0x%x)\n", addr, end_addr);
122 for (int i = 0; i < len; ++i)
123 mem.b[(addr + i) ^ MEM_SIZE_M1] = buf[4 + i];
131 fprintf(stderr, "invalid start address record: %s\n", line);
134 entry_point = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
139 fprintf(stderr, "invalid extended linear address record: %s\n", line);
142 base = (buf[4] << 24) | (buf[5] << 16);
146 fprintf(stderr, "invalid start linear address record: %s\n", line);
149 entry_point = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
152 fprintf(stderr, "unknown record type: 0x%x\n", buf[3]);
157 fprintf(stderr, "no EOF record\n");
165 int read_byte(void *context, int addr) {
168 case 0177560: // dl11 rcv csr
171 case 0177564: // dl11 xmt csr
175 if (addr < 0 || addr >= MEM_SIZE) {
176 fprintf(stderr, "invalid read byte: %06o\n", addr);
179 data = mem.b[addr ^ MEM_SIZE_M1];
183 fprintf(stderr, "addr=%06o rd=%03o\n", addr, data);
188 int read_word(void *context, int addr) {
194 case 0177560: // dl11 rcv csr
197 case 0177562: // dl11 rcv buf
206 #if 0 // just keep sending 0xff at EOF
214 if (addr < 0 || addr >= MEM_SIZE || (addr & 1)) {
215 fprintf(stderr, "invalid read word: %06o\n", addr);
218 data = mem.w[(addr ^ MEM_SIZE_M2) >> 1];
222 fprintf(stderr, "addr=%06o rd=%06o\n", addr, data);
227 void write_byte(void *context, int addr, int data) {
229 fprintf(stderr, "addr=%06o wr=%03o\n", addr, data);
232 case 0177566: // dl11 xmt buf
246 if (addr < 0 || addr >= MEM_SIZE) {
247 fprintf(stderr, "invalid write byte: %06o\n", addr);
250 mem.b[addr ^ MEM_SIZE_M1] = data;
254 void write_word(void *context, int addr, int data) {
256 fprintf(stderr, "addr=%06o wr=%06o\n", addr, data);
262 if (addr < 0 || addr >= MEM_SIZE || (addr & 1)) {
263 fprintf(stderr, "invalid write word: %06o\n", addr);
266 mem.w[(addr ^ MEM_SIZE_M2) >> 1] = data;
271 int32 ReadE(int32 va) {
272 return read_word(NULL, va);
275 int32 ReadW(int32 va) {
276 return read_word(NULL, va);
279 int32 ReadB(int32 va) {
280 return read_byte(NULL, va);
283 int32 ReadCW(int32 va) {
284 return read_word(NULL, va);
287 int32 ReadMW(int32 va) {
289 return read_word(NULL, va);
292 int32 ReadMB(int32 va) {
294 return read_byte(NULL, va);
297 int32 PReadW(int32 pa) {
298 return read_word(NULL, pa);
301 int32 PReadB(int32 pa) {
302 return read_byte(NULL, pa);
305 void WriteW(int32 data, int32 va) {
306 write_word(NULL, va, data);
309 void WriteB(int32 data, int32 va) {
310 write_byte(NULL, va, data);
313 void WriteCW(int32 data, int32 va) {
314 write_word(NULL, va, data);
317 void PWriteW(int32 data, int32 pa) {
318 write_word(NULL, pa, data);
321 void PWriteB (int32 data, int32 pa) {
322 write_byte(NULL, pa, data);
325 int m68k_service_trap(unsigned int vector) {
326 //fprintf(stderr, "trap %x\n", vector);
327 if (vector == EXCEPTION_TRAP_BASE + 0xe) // TBI68K bye command
333 int main(int argc, char **argv) {
335 printf("usage: %s image.ihx\n", argv[0]);
338 int entry_point = load_ihx(argv[1]);
341 // emulate Tutor firmware for TBI68K
342 mem.l[(0 ^ MEM_SIZE_M4) >> 2] = 0x8000; // initial SP
343 mem.l[(4 ^ MEM_SIZE_M4) >> 2] = 0x900; // initial PC
348 saved_PC = entry_point;
354 "pc=%06o r0=%06o r1=%06o r2=%06o r3=%06o r4=%06o r5=%06o sp=%06o psw=%06o nf=%d zf=%d vf=%d cf=%d\n",
364 (PSW >> PSW_V_N) & 1,
365 (PSW >> PSW_V_Z) & 1,
366 (PSW >> PSW_V_V) & 1,
374 struct cpu_68000 cpu;
375 cpu_68000_init(&cpu, read_byte, NULL, write_byte, NULL);
376 cpu_68000_reset(&cpu);
382 "pc=%06o a=%03o b=%03o s=%06o x=%06o p=%03o hf=%d if=%d nf=%d zf=%d vf=%d cf=%d\n",
398 cpu_68000_execute(&cpu);