OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.25/] [sim/] [command.c] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 hellwig
/*
2
 * command.c -- command interpreter
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <setjmp.h>
10
 
11
#include "common.h"
12
#include "console.h"
13
#include "error.h"
14
#include "except.h"
15
#include "command.h"
16
#include "asm.h"
17
#include "disasm.h"
18
#include "cpu.h"
19
#include "mmu.h"
20
#include "memory.h"
21
#include "timer.h"
22
#include "dspkbd.h"
23
#include "term.h"
24
#include "disk.h"
25
#include "graph.h"
26
 
27
 
28
#define MAX_TOKENS      10
29
 
30
 
31
static Bool quit;
32
 
33
 
34
static void help(void) {
35
  cPrintf("valid commands are:\n");
36
  cPrintf("  +  <num1> <num2>  add and subtract <num1> and <num2>\n");
37
  cPrintf("  a                 assemble starting at PC\n");
38
  cPrintf("  a  <addr>         assemble starting at <addr>\n");
39
  cPrintf("  u                 unassemble 16 instrs starting at PC\n");
40
  cPrintf("  u  <addr>         unassemble 16 instrs starting at <addr>\n");
41
  cPrintf("  u  <addr> <cnt>   unassemble <cnt> instrs starting at <addr>\n");
42
  cPrintf("  b                 reset break\n");
43
  cPrintf("  b  <addr>         set break at <addr>\n");
44
  cPrintf("  c                 continue execution\n");
45
  cPrintf("  c  <cnt>          continue execution <cnt> times\n");
46
  cPrintf("  s                 single-step one instruction\n");
47
  cPrintf("  s  <cnt>          single-step <cnt> instructions\n");
48
  cPrintf("  @                 show PC\n");
49
  cPrintf("  @  <addr>         set PC to <addr>\n");
50
  cPrintf("  p                 show PSW\n");
51
  cPrintf("  p  <data>         set PSW to <data>\n");
52
  cPrintf("  r                 show all registers\n");
53
  cPrintf("  r  <reg>          show register <reg>\n");
54
  cPrintf("  r  <reg> <data>   set register <reg> to <data>\n");
55
  cPrintf("  d                 dump 256 bytes starting at PC\n");
56
  cPrintf("  d  <addr>         dump 256 bytes starting at <addr>\n");
57
  cPrintf("  d  <addr> <cnt>   dump <cnt> bytes starting at <addr>\n");
58
  cPrintf("  mw                show memory word at PC\n");
59
  cPrintf("  mw <addr>         show memory word at <addr>\n");
60
  cPrintf("  mw <addr> <data>  set memory word at <addr> to <data>\n");
61
  cPrintf("  mh                show memory halfword at PC\n");
62
  cPrintf("  mh <addr>         show memory halfword at <addr>\n");
63
  cPrintf("  mh <addr> <data>  set memory halfword at <addr> to <data>\n");
64
  cPrintf("  mb                show memory byte at PC\n");
65
  cPrintf("  mb <addr>         show memory byte at <addr>\n");
66
  cPrintf("  mb <addr> <data>  set memory byte at <addr> to <data>\n");
67
  cPrintf("  t                 show TLB contents\n");
68
  cPrintf("  t  <i>            show TLB contents at <i>\n");
69
  cPrintf("  t  <i> p <data>   set TLB contents at <i> to page <data>\n");
70
  cPrintf("  t  <i> f <data>   set TLB contents at <i> to frame <data>\n");
71
  cPrintf("  i                 initialize hardware\n");
72
  cPrintf("  q                 quit simulator\n");
73
}
74
 
75
 
76
static char *cause[32] = {
77
  /*  0 */  "terminal 0 transmitter interrupt",
78
  /*  1 */  "terminal 0 receiver interrupt",
79
  /*  2 */  "terminal 1 transmitter interrupt",
80
  /*  3 */  "terminal 1 receiver interrupt",
81
  /*  4 */  "keyboard interrupt",
82
  /*  5 */  "unknown interrupt",
83
  /*  6 */  "unknown interrupt",
84
  /*  7 */  "unknown interrupt",
85
  /*  8 */  "disk interrupt",
86
  /*  9 */  "unknown interrupt",
87
  /* 10 */  "unknown interrupt",
88
  /* 11 */  "unknown interrupt",
89
  /* 12 */  "unknown interrupt",
90
  /* 13 */  "unknown interrupt",
91
  /* 14 */  "timer interrupt",
92
  /* 15 */  "unknown interrupt",
93
  /* 16 */  "bus timeout exception",
94
  /* 17 */  "illegal instruction exception",
95
  /* 18 */  "privileged instruction exception",
96
  /* 19 */  "divide instruction exception",
97
  /* 20 */  "trap instruction exception",
98
  /* 21 */  "TLB miss exception",
99
  /* 22 */  "TLB write exception",
100
  /* 23 */  "TLB invalid exception",
101
  /* 24 */  "illegal address exception",
102
  /* 25 */  "privileged address exception",
103
  /* 26 */  "unknown exception",
104
  /* 27 */  "unknown exception",
105
  /* 28 */  "unknown exception",
106
  /* 29 */  "unknown exception",
107
  /* 30 */  "unknown exception",
108
  /* 31 */  "unknown exception"
109
};
110
 
111
 
112
static char *exceptionToString(int exception) {
113
  if (exception < 0 ||
114
      exception >= sizeof(cause)/sizeof(cause[0])) {
115
    error("exception number out of bounds");
116
  }
117
  return cause[exception];
118
}
119
 
120
 
121
static Bool getHexNumber(char *str, Word *valptr) {
122
  char *end;
123
 
124
  *valptr = strtoul(str, &end, 16);
125
  return *end == '\0';
126
}
127
 
128
 
129
static Bool getDecNumber(char *str, int *valptr) {
130
  char *end;
131
 
132
  *valptr = strtoul(str, &end, 10);
133
  return *end == '\0';
134
}
135
 
136
 
137
static void showPC(void) {
138
  Word pc, psw;
139
  Word instr;
140
 
141
  pc = cpuGetPC();
142
  psw = cpuGetPSW();
143
  instr = mmuReadWord(pc, psw & PSW_UM);
144
  cPrintf("PC   %08X     [PC]   %08X   %s\n",
145
          pc, instr, disasm(instr, pc));
146
}
147
 
148
 
149
static void showBreakAndTotal(void) {
150
  Word brk;
151
  Word tot;
152
 
153
  brk = cpuGetBreak();
154
  tot = cpuGetTotal();
155
  cPrintf("Brk  ");
156
  if (cpuTestBreak()) {
157
    cPrintf("%08X", brk);
158
  } else {
159
    cPrintf("--------");
160
  }
161
  cPrintf("     Total  %08X   instructions\n", tot);
162
}
163
 
164
 
165
static void showIRQ(void) {
166
  Word irq;
167
  int i;
168
 
169
  irq = cpuGetIRQ();
170
  cPrintf("IRQ                            ");
171
  for (i = 15; i >= 0; i--) {
172
    cPrintf("%c", irq & (1 << i) ? '1' : '0');
173
  }
174
  cPrintf("\n");
175
}
176
 
177
 
178
static void showPSW(void) {
179
  Word psw;
180
  int i;
181
 
182
  psw = cpuGetPSW();
183
  cPrintf("     xxxx  V  UPO  IPO  IACK   MASK\n");
184
  cPrintf("PSW  ");
185
  for (i = 31; i >= 0; i--) {
186
    if (i == 27 || i == 26 || i == 23 || i == 20 || i == 15) {
187
      cPrintf("  ");
188
    }
189
    cPrintf("%c", psw & (1 << i) ? '1' : '0');
190
  }
191
  cPrintf("\n");
192
}
193
 
194
 
195
static void doArith(char *tokens[], int n) {
196
  Word num1, num2, num3, num4;
197
 
198
  if (n == 3) {
199
    if (!getHexNumber(tokens[1], &num1)) {
200
      cPrintf("illegal first number\n");
201
      return;
202
    }
203
    if (!getHexNumber(tokens[2], &num2)) {
204
      cPrintf("illegal second number\n");
205
      return;
206
    }
207
    num3 = num1 + num2;
208
    num4 = num1 - num2;
209
    cPrintf("add = %08X, sub = %08X\n", num3, num4);
210
  } else {
211
    help();
212
  }
213
}
214
 
215
 
216
static void doAssemble(char *tokens[], int n) {
217
  Word addr;
218
  Word psw;
219
  char prompt[30];
220
  char *line;
221
  char *msg;
222
  Word instr;
223
 
224
  if (n == 1) {
225
    addr = cpuGetPC();
226
  } else if (n == 2) {
227
    if (!getHexNumber(tokens[1], &addr)) {
228
      cPrintf("illegal address\n");
229
      return;
230
    }
231
  } else {
232
    help();
233
    return;
234
  }
235
  addr &= ~0x00000003;
236
  psw = cpuGetPSW();
237
  while (1) {
238
    sprintf(prompt, "ASM @ %08X: ", addr);
239
    line = cGetLine(prompt);
240
    if (*line == '\0' || *line == '\n') {
241
      break;
242
    }
243
    cAddHist(line);
244
    msg = asmInstr(line, addr, &instr);
245
    if (msg != NULL) {
246
      cPrintf("%s\n", msg);
247
    } else {
248
      mmuWriteWord(addr, instr, psw & PSW_UM);
249
      addr += 4;
250
    }
251
  }
252
}
253
 
254
 
255
static void doUnassemble(char *tokens[], int n) {
256
  Word addr, count;
257
  Word psw;
258
  int i;
259
  Word instr;
260
 
261
  if (n == 1) {
262
    addr = cpuGetPC();
263
    count = 16;
264
  } else if (n == 2) {
265
    if (!getHexNumber(tokens[1], &addr)) {
266
      cPrintf("illegal address\n");
267
      return;
268
    }
269
    count = 16;
270
  } else if (n == 3) {
271
    if (!getHexNumber(tokens[1], &addr)) {
272
      cPrintf("illegal address\n");
273
      return;
274
    }
275
    if (!getHexNumber(tokens[2], &count)) {
276
      cPrintf("illegal count\n");
277
      return;
278
    }
279
    if (count == 0) {
280
      return;
281
    }
282
  } else {
283
    help();
284
    return;
285
  }
286
  addr &= ~0x00000003;
287
  psw = cpuGetPSW();
288
  for (i = 0; i < count; i++) {
289
    instr = mmuReadWord(addr, psw & PSW_UM);
290
    cPrintf("%08X:  %08X    %s\n",
291
            addr, instr, disasm(instr, addr));
292
    if (addr + 4 < addr) {
293
      /* wrap-around */
294
      break;
295
    }
296
    addr += 4;
297
  }
298
}
299
 
300
 
301
static void doBreak(char *tokens[], int n) {
302
  Word addr;
303
 
304
  if (n == 1) {
305
    cpuResetBreak();
306
    showBreakAndTotal();
307
  } else if (n == 2) {
308
    if (!getHexNumber(tokens[1], &addr)) {
309
      cPrintf("illegal address\n");
310
      return;
311
    }
312
    addr &= ~0x00000003;
313
    cpuSetBreak(addr);
314
    showBreakAndTotal();
315
  } else {
316
    help();
317
  }
318
}
319
 
320
 
321
static void doContinue(char *tokens[], int n) {
322
  Word count, i;
323
  Word addr;
324
 
325
  if (n == 1) {
326
    count = 1;
327
  } else if (n == 2) {
328
    if (!getHexNumber(tokens[1], &count) || count == 0) {
329
      cPrintf("illegal count\n");
330
      return;
331
    }
332
  } else {
333
    help();
334
    return;
335
  }
336
  cPrintf("CPU is running, press ^C to interrupt...\n");
337
  for (i = 0; i < count; i++) {
338
    cpuRun();
339
  }
340
  addr = cpuGetPC();
341
  cPrintf("Break at %08X\n", addr);
342
  showPC();
343
}
344
 
345
 
346
static void doStep(char *tokens[], int n) {
347
  Word count, i;
348
 
349
  if (n == 1) {
350
    count = 1;
351
  } else if (n == 2) {
352
    if (!getHexNumber(tokens[1], &count) || count == 0) {
353
      cPrintf("illegal count\n");
354
      return;
355
    }
356
  } else {
357
    help();
358
    return;
359
  }
360
  for (i = 0; i < count; i++) {
361
    cpuStep();
362
  }
363
  showPC();
364
}
365
 
366
 
367
static void doPC(char *tokens[], int n) {
368
  Word addr;
369
 
370
  if (n == 1) {
371
    showPC();
372
  } else if (n == 2) {
373
    if (!getHexNumber(tokens[1], &addr)) {
374
      cPrintf("illegal address\n");
375
      return;
376
    }
377
    addr &= ~0x00000003;
378
    cpuSetPC(addr);
379
    showPC();
380
  } else {
381
    help();
382
  }
383
}
384
 
385
 
386
static void explainPSW(Word data) {
387
  int i;
388
 
389
  cPrintf("interrupt vector                   : %s (%s)\n",
390
          data & PSW_V ? "on " : "off",
391
          data & PSW_V ? "RAM" : "ROM");
392
  cPrintf("current user mode                  : %s (%s)\n",
393
          data & PSW_UM ? "on " : "off",
394
          data & PSW_UM ? "user" : "kernel");
395
  cPrintf("previous user mode                 : %s (%s)\n",
396
          data & PSW_PUM ? "on " : "off",
397
          data & PSW_PUM ? "user" : "kernel");
398
  cPrintf("old user mode                      : %s (%s)\n",
399
          data & PSW_OUM ? "on " : "off",
400
          data & PSW_OUM ? "user" : "kernel");
401
  cPrintf("current interrupt enable           : %s (%s)\n",
402
          data & PSW_IE ? "on " : "off",
403
          data & PSW_IE ? "enabled" : "disabled");
404
  cPrintf("previous interrupt enable          : %s (%s)\n",
405
          data & PSW_PIE ? "on " : "off",
406
          data & PSW_PIE ? "enabled" : "disabled");
407
  cPrintf("old interrupt enable               : %s (%s)\n",
408
          data & PSW_OIE ? "on " : "off",
409
          data & PSW_OIE ? "enabled" : "disabled");
410
  cPrintf("last interrupt acknowledged        : %02X  (%s)\n",
411
          (data & PSW_PRIO_MASK) >> 16,
412
          exceptionToString((data & PSW_PRIO_MASK) >> 16));
413
  for (i = 15; i >= 0; i--) {
414
    cPrintf("%-35s: %s (%s)\n",
415
            exceptionToString(i),
416
            data & (1 << i) ? "on " : "off",
417
            data & (1 << i) ? "enabled" : "disabled");
418
  }
419
}
420
 
421
 
422
static void doPSW(char *tokens[], int n) {
423
  Word data;
424
 
425
  if (n == 1) {
426
    data = cpuGetPSW();
427
    showPSW();
428
    showIRQ();
429
    explainPSW(data);
430
  } else if (n == 2) {
431
    if (!getHexNumber(tokens[1], &data)) {
432
      cPrintf("illegal data\n");
433
      return;
434
    }
435
    data &= 0x0FFFFFFF;
436
    cpuSetPSW(data);
437
    showPSW();
438
    showIRQ();
439
    explainPSW(data);
440
  } else {
441
    help();
442
  }
443
}
444
 
445
 
446
static void doRegister(char *tokens[], int n) {
447
  int i, j;
448
  int reg;
449
  Word data;
450
 
451
  if (n == 1) {
452
    for (i = 0; i < 8; i++) {
453
      for (j = 0; j < 4; j++) {
454
        reg = 8 * j + i;
455
        data = cpuGetReg(reg);
456
        cPrintf("$%-2d  %08X     ", reg, data);
457
      }
458
      cPrintf("\n");
459
    }
460
    showPSW();
461
    showIRQ();
462
    showBreakAndTotal();
463
    showPC();
464
  } else if (n == 2) {
465
    if (!getDecNumber(tokens[1], &reg) || reg < 0 || reg >= 32) {
466
      cPrintf("illegal register number\n");
467
      return;
468
    }
469
    data = cpuGetReg(reg);
470
    cPrintf("$%-2d  %08X\n", reg, data);
471
  } else if (n == 3) {
472
    if (!getDecNumber(tokens[1], &reg) || reg < 0 || reg >= 32) {
473
      cPrintf("illegal register number\n");
474
      return;
475
    }
476
    if (!getHexNumber(tokens[2], &data)) {
477
      cPrintf("illegal data\n");
478
      return;
479
    }
480
    cpuSetReg(reg, data);
481
  } else {
482
    help();
483
  }
484
}
485
 
486
 
487
static void doDump(char *tokens[], int n) {
488
  Word addr, count;
489
  Word psw;
490
  Word lo, hi, curr;
491
  int lines, i, j;
492
  Word tmp;
493
  Byte c;
494
 
495
  if (n == 1) {
496
    addr = cpuGetPC();
497
    count = 16 * 16;
498
  } else if (n == 2) {
499
    if (!getHexNumber(tokens[1], &addr)) {
500
      cPrintf("illegal address\n");
501
      return;
502
    }
503
    count = 16 * 16;
504
  } else if (n == 3) {
505
    if (!getHexNumber(tokens[1], &addr)) {
506
      cPrintf("illegal address\n");
507
      return;
508
    }
509
    if (!getHexNumber(tokens[2], &count)) {
510
      cPrintf("illegal count\n");
511
      return;
512
    }
513
    if (count == 0) {
514
      return;
515
    }
516
  } else {
517
    help();
518
    return;
519
  }
520
  psw = cpuGetPSW();
521
  lo = addr & ~0x0000000F;
522
  hi = addr + count - 1;
523
  if (hi < lo) {
524
    /* wrap-around */
525
    hi = 0xFFFFFFFF;
526
  }
527
  lines = (hi - lo + 16) >> 4;
528
  curr = lo;
529
  for (i = 0; i < lines; i++) {
530
    cPrintf("%08X:  ", curr);
531
    for (j = 0; j < 16; j++) {
532
      tmp = curr + j;
533
      if (tmp < addr || tmp > hi) {
534
        cPrintf("  ");
535
      } else {
536
        c = mmuReadByte(tmp, psw & PSW_UM);
537
        cPrintf("%02X", c);
538
      }
539
      cPrintf(" ");
540
    }
541
    cPrintf("  ");
542
    for (j = 0; j < 16; j++) {
543
      tmp = curr + j;
544
      if (tmp < addr || tmp > hi) {
545
        cPrintf(" ");
546
      } else {
547
        c = mmuReadByte(tmp, psw & PSW_UM);
548
        if (c >= 32 && c <= 126) {
549
          cPrintf("%c", c);
550
        } else {
551
          cPrintf(".");
552
        }
553
      }
554
    }
555
    cPrintf("\n");
556
    curr += 16;
557
  }
558
}
559
 
560
 
561
static void doMemoryWord(char *tokens[], int n) {
562
  Word psw;
563
  Word addr;
564
  Word data;
565
  Word tmpData;
566
 
567
  psw = cpuGetPSW();
568
  if (n == 1) {
569
    addr = cpuGetPC();
570
    data = mmuReadWord(addr, psw & PSW_UM);
571
    cPrintf("%08X:  %08X\n", addr, data);
572
  } else if (n == 2) {
573
    if (!getHexNumber(tokens[1], &addr)) {
574
      cPrintf("illegal address\n");
575
      return;
576
    }
577
    data = mmuReadWord(addr, psw & PSW_UM);
578
    cPrintf("%08X:  %08X\n", addr, data);
579
  } else if (n == 3) {
580
    if (!getHexNumber(tokens[1], &addr)) {
581
      cPrintf("illegal address\n");
582
      return;
583
    }
584
    if (!getHexNumber(tokens[2], &tmpData)) {
585
      cPrintf("illegal data\n");
586
      return;
587
    }
588
    data = tmpData;
589
    mmuWriteWord(addr, data, psw & PSW_UM);
590
  } else {
591
    help();
592
  }
593
}
594
 
595
 
596
static void doMemoryHalf(char *tokens[], int n) {
597
  Word psw;
598
  Word addr;
599
  Half data;
600
  Word tmpData;
601
 
602
  psw = cpuGetPSW();
603
  if (n == 1) {
604
    addr = cpuGetPC();
605
    data = mmuReadHalf(addr, psw & PSW_UM);
606
    cPrintf("%08X:  %04X\n", addr, data);
607
  } else if (n == 2) {
608
    if (!getHexNumber(tokens[1], &addr)) {
609
      cPrintf("illegal address\n");
610
      return;
611
    }
612
    data = mmuReadHalf(addr, psw & PSW_UM);
613
    cPrintf("%08X:  %04X\n", addr, data);
614
  } else if (n == 3) {
615
    if (!getHexNumber(tokens[1], &addr)) {
616
      cPrintf("illegal address\n");
617
      return;
618
    }
619
    if (!getHexNumber(tokens[2], &tmpData)) {
620
      cPrintf("illegal data\n");
621
      return;
622
    }
623
    data = (Half) tmpData;
624
    mmuWriteHalf(addr, data, psw & PSW_UM);
625
  } else {
626
    help();
627
  }
628
}
629
 
630
 
631
static void doMemoryByte(char *tokens[], int n) {
632
  Word psw;
633
  Word addr;
634
  Byte data;
635
  Word tmpData;
636
 
637
  psw = cpuGetPSW();
638
  if (n == 1) {
639
    addr = cpuGetPC();
640
    data = mmuReadByte(addr, psw & PSW_UM);
641
    cPrintf("%08X:  %02X\n", addr, data);
642
  } else if (n == 2) {
643
    if (!getHexNumber(tokens[1], &addr)) {
644
      cPrintf("illegal address\n");
645
      return;
646
    }
647
    data = mmuReadByte(addr, psw & PSW_UM);
648
    cPrintf("%08X:  %02X\n", addr, data);
649
  } else if (n == 3) {
650
    if (!getHexNumber(tokens[1], &addr)) {
651
      cPrintf("illegal address\n");
652
      return;
653
    }
654
    if (!getHexNumber(tokens[2], &tmpData)) {
655
      cPrintf("illegal data\n");
656
      return;
657
    }
658
    data = (Byte) tmpData;
659
    mmuWriteByte(addr, data, psw & PSW_UM);
660
  } else {
661
    help();
662
  }
663
}
664
 
665
 
666
static void doTLB(char *tokens[], int n) {
667
  int index;
668
  TLB_Entry tlbEntry;
669
  Word data;
670
 
671
  if (n == 1) {
672
    for (index = 0; index < TLB_SIZE; index++) {
673
      tlbEntry = mmuGetTLB(index);
674
      cPrintf("TLB[%02d]    page  %08X    frame  %08X  %c  %c\n",
675
              index, tlbEntry.page, tlbEntry.frame,
676
              tlbEntry.write ? 'w' : '-',
677
              tlbEntry.valid ? 'v' : '-');
678
    }
679
    cPrintf("Index(1)   %08X\n", mmuGetIndex());
680
    cPrintf("EntryHi(2) %08X\n", mmuGetEntryHi());
681
    cPrintf("EntryLo(3) %08X\n", mmuGetEntryLo());
682
    cPrintf("BadAddr(4) %08X\n", mmuGetBadAddr());
683
  } else if (n == 2) {
684
    if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
685
      cPrintf("illegal TLB index\n");
686
      return;
687
    }
688
    tlbEntry = mmuGetTLB(index);
689
    cPrintf("TLB[%02d]    page  %08X    frame  %08X  %c  %c\n",
690
            index, tlbEntry.page, tlbEntry.frame,
691
            tlbEntry.write ? 'w' : '-',
692
            tlbEntry.valid ? 'v' : '-');
693
  } else if (n == 3) {
694
    help();
695
  } else if (n == 4) {
696
    if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
697
      cPrintf("illegal TLB index\n");
698
      return;
699
    }
700
    if (!getHexNumber(tokens[3], &data)) {
701
      cPrintf("illegal data\n");
702
      return;
703
    }
704
    tlbEntry = mmuGetTLB(index);
705
    if (strcmp(tokens[2], "p") == 0) {
706
      tlbEntry.page = data & PAGE_MASK;
707
    } else
708
    if (strcmp(tokens[2], "f") == 0) {
709
      tlbEntry.frame = data & PAGE_MASK;
710
      tlbEntry.write = data & TLB_WRITE ? true : false;
711
      tlbEntry.valid = data & TLB_VALID ? true : false;
712
    } else {
713
      cPrintf("TLB selector is not one of 'p' or 'f'\n");
714
      return;
715
    }
716
    mmuSetTLB(index, tlbEntry);
717
    cPrintf("TLB[%02d]    page  %08X    frame  %08X  %c  %c\n",
718
            index, tlbEntry.page, tlbEntry.frame,
719
            tlbEntry.write ? 'w' : '-',
720
            tlbEntry.valid ? 'v' : '-');
721
  } else {
722
    help();
723
  }
724
}
725
 
726
 
727
static void doInit(char *tokens[], int n) {
728
  if (n == 1) {
729
    timerReset();
730
    displayReset();
731
    keyboardReset();
732
    termReset();
733
    diskReset();
734
    graphReset();
735
    memoryReset();
736
    mmuReset();
737
    cpuReset();
738
  } else {
739
    help();
740
  }
741
}
742
 
743
 
744
static void doQuit(char *tokens[], int n) {
745
  if (n == 1) {
746
    quit = true;
747
  } else {
748
    help();
749
  }
750
}
751
 
752
 
753
typedef struct {
754
  char *name;
755
  void (*cmdProc)(char *tokens[], int n);
756
} Command;
757
 
758
 
759
static Command commands[] = {
760
  { "+",  doArith },
761
  { "a",  doAssemble },
762
  { "u",  doUnassemble },
763
  { "b",  doBreak },
764
  { "c",  doContinue },
765
  { "s",  doStep },
766
  { "@",  doPC },
767
  { "p",  doPSW },
768
  { "r",  doRegister },
769
  { "d",  doDump },
770
  { "mw", doMemoryWord },
771
  { "mh", doMemoryHalf },
772
  { "mb", doMemoryByte },
773
  { "t",  doTLB },
774
  { "i",  doInit },
775
  { "q",  doQuit }
776
};
777
 
778
 
779
static Bool doCommand(char *line) {
780
  char *tokens[MAX_TOKENS];
781
  int n;
782
  char *p;
783
  int i;
784
 
785
  n = 0;
786
  p = strtok(line, " \t\n");
787
  while (p != NULL) {
788
    if (n == MAX_TOKENS) {
789
      cPrintf("too many tokens on line\n");
790
      return false;
791
    }
792
    tokens[n++] = p;
793
    p = strtok(NULL, " \t\n");
794
  }
795
  if (n == 0) {
796
    return false;
797
  }
798
  quit = false;
799
  for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
800
    if (strcmp(commands[i].name, tokens[0]) == 0) {
801
      (*commands[i].cmdProc)(tokens, n);
802
      return quit;
803
    }
804
  }
805
  help();
806
  return false;
807
}
808
 
809
 
810
static char *article(char firstLetterOfNoun) {
811
  switch (firstLetterOfNoun) {
812
    case 'a':
813
    case 'e':
814
    case 'i':
815
    case 'o':
816
    case 'u':
817
      return "An";
818
    default:
819
      return "A";
820
  }
821
}
822
 
823
 
824
static void interactiveException(int exception) {
825
  char *what;
826
 
827
  what = exceptionToString(exception);
828
  cPrintf("\n");
829
  cPrintf("NOTE: %s %s occurred while executing the command.\n",
830
          article(*what), what);
831
  cPrintf("      This event will not alter the state of the CPU.\n");
832
}
833
 
834
 
835
Bool execCommand(char *line) {
836
  jmp_buf myEnvironment;
837
  int exception;
838
  Bool quit;
839
 
840
  exception = setjmp(myEnvironment);
841
  if (exception == 0) {
842
    /* initialization */
843
    pushEnvironment(&myEnvironment);
844
    quit = doCommand(line);
845
  } else {
846
    /* an exception was thrown */
847
    interactiveException(exception);
848
    quit = false;
849
  }
850
  popEnvironment();
851
  return quit;
852
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.