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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [sim/] [command.c] - Blame information for rev 48

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

powered by: WebSVN 2.1.0

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