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

Subversion Repositories eco32

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

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

powered by: WebSVN 2.1.0

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