1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19: 20:
21:
22: #include "cmdsvc.h"
23: #include "help.h"
24: #include <tk/dbgspt.h>
25:
26: #define DEF_MEM_SIZE 64
27: #define DEF_DA_STEP 16
28: #define MAX_DSP_CNT 64
29: #define MAX_RANGE 0x1000000
30: #define IMPLICIT_SIZE 0x1000
31:
32: EXPORT UB lineBuf[L_LINE];
33: EXPORT W killProcReq;
34:
35: #define L_SYMBOL 23
36: #define SETDT_SZ 128
37:
38: #define CMD_FINISH (9999)
39:
40: EXPORT W errinfo;
41: LOCAL W errcode;
42:
43: LOCAL UW dAddr;
44: LOCAL UW mAddr;
45: LOCAL UW daAddr;
46: LOCAL UW cAddr;
47: LOCAL W cLen;
48:
49: LOCAL W token;
50: LOCAL UW tokenVal;
51: LOCAL UB *tokenStr;
52: LOCAL W tokenLen;
53: LOCAL UB tokenSym[L_SYMBOL + 1];
54: LOCAL UB symExt[2];
55: LOCAL UB *lptr;
56:
57: #define PROMPT "TM> "
58:
59:
60: #define tEOL 0x00
61: #define tEOC 0x01
62: #define tDLM 0x02
63: #define tSIZ 0x11
64: #define tOPADD 0x12
65: #define tOPSUB 0x13
66: #define tOPMUL 0x14
67: #define tOPDIV 0x15
68: #define tOPIND 0x16
69: #define tEOD 0x17
70: #define tUP 0x18
71: #define tSYM 0x20
72: #define tNUM 0x21
73: #define tSTR 0x22
74: #define tERRR 0x100
75: #define tERCH 0x100
76: #define tERNUM 0x101
77:
78:
79: #define isSpace(c) ((c) && (c) <= ' ')
80: #define isNum(c) ((c) >= '0' && (c) <= '9')
81: #define isAlpha(c) ( ((c) >= 'A' && (c) <= 'Z') ||\
82: ((c) >= 'a' && (c) <= 'z') )
83: #define isAlNum(c) (isNum(c) || isAlpha(c))
84: #define isSym(c) (isAlpha(c) || c == '$' || c == '_' ||\
85: c == '?' || c == '@')
86: #define isExtSym(c) ((c) && ((c) == symExt[0] || (c) == symExt[1]))
87:
88:
89: #define ALIGN_L(v, unit) ((v) & ~((unit) - 1))
90: #define ALIGN_U(v, unit) (((v) + (unit) - 1) & ~((unit) - 1))
91:
92:
93: #define return_er(er) return (errcode = er)
94: #define er_return(er) {errcode = er; return;}
95: #define oer_return(er) {if ((er) == E_NOEXS)\
96: errcode = E_ONOEXS;\
97: else errcode = er;\
98: return;}
99:
100: #define DB16 0x00000
101: #define DB10 0x10000
102:
103: 104: 105:
106: LOCAL void dspError(void)
107: {
108: UB *mp = NULL;
109:
110: if (token >= tERRR) {
111: switch(token) {
112: case tERCH: mp = "Illegal Character"; break;
113: case tERNUM: mp = "Illegal Number Format"; break;
114: }
115: } else {
116: if (errinfo < 0) errcode = errinfo;
117: switch(errcode) {
118: case E_MACV: mp = "Illegal Address"; break;
119: case E_ROM: mp = "ROM Address"; break;
120: case E_LESS: if (token <= tEOC)
121: {mp = "Less Parameter"; break;}
122: case E_PAR: mp = "Illegal Parameter"; break;
123: case E_ID: mp = "Illegal ID Number"; break;
124: case E_CTX: mp = "Context Error"; break;
125: case E_LIMIT: mp = "Too Many Parameters"; break;
126: case E_OBJ: mp = "Abnormal Object Status"; break;
127: case E_NOSPT: mp = "Not Supported"; break;
128: case E_NOEXS: mp = "Unknown Device"; break;
129: case E_IO: mp = "I/O Error"; break;
130: case E_RONLY: mp = "Read Only"; break;
131: case E_NOMDA: mp = "No Media"; break;
132: case E_PROTECT: mp = "Write Protected"; break;
133:
134: case E_CMD: mp = "Unknown Command"; break;
135: case E_RANGE: mp = "Illegal Address Range"; break;
136: case E_EMPTY: mp = "Empty String"; break;
137: case E_ILREG: mp = "Unknown Register Name"; break;
138: case E_PC: mp = "Illegal PC Value"; break;
139: case E_BOOT: mp = "No Bootable Disk"; break;
140:
141: case E_PROTO: mp = "Unknown Load Protocol"; break;
142: case E_NOADDR: mp = "No Load Address"; break;
143: case E_LOADFMT: mp = "Illegal S-Format Record"; break;
144: case E_LOAD: mp = "Loading Error"; break;
145: case E_CANCEL: mp = "Loading Cancelled"; break;
146: case E_XMODEM: mp = "XMODEM Protocol Error"; break;
147:
148: case E_BPATR: mp = "Unknown Break Point Attribute"; break;
149: case E_BPBAD: mp = "Illegal Break Point"; break;
150: case E_BPDSLT: mp = "Break Point at Delayed Slot"; break;
151: case E_BPROM: mp = "Break Point in ROM"; break;
152: case E_BPCMD: mp = "Too Long Break Point Command"; break;
153: case E_BPUDF: mp = "Undefined Break Point"; break;
154: case E_SBPOVR: mp = "Too Many Software Break Points"; break;
155: case E_HBPOVR: mp = "Too Many Hardware Break Points"; break;
156:
157: case E_ONOEXS: mp = "Noexistent Object"; break;
158: }
159: }
160: if (mp) {
161: DSP_F3(S,"ERR: ", S,mp, CH,'\n');
162: } else {
163: DSP_F3(S,"ERR: [", 08X,errcode, S,"]\n");
164: }
165: }
166: 167: 168:
169: LOCAL W getLine(UB *msg)
170: {
171: if (msg) DSP_S(msg);
172: memset(lineBuf, 0, sizeof(lineBuf));
173: return getString(lptr = lineBuf);
174: }
175: 176: 177:
178: LOCAL void skipSpace(void)
179: {
180: while (isSpace(*lptr)) lptr++;
181: }
182: 183: 184:
185: LOCAL W getHexVal(UB **ptr)
186: {
187: W c;
188: UW v;
189: UB *p;
190:
191: p = *ptr;
192: for (v = 0; ((c = *p) >= '0' && c <= '9') ||
193: (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); p++) {
194: if (v >= 0x10000000) break;
195: v <<= 4;
196: v += (c >= 'a' ? (c - 'a' + 10) :
197: (c >= 'A' ? (c - 'A' + 10) : ( c - '0')));
198: }
199: *ptr = p;
200: return v;
201: }
202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222:
223: LOCAL W getToken(W defbase)
224: {
225: W c, i, base;
226:
227: tokenVal = 0;
228: skipSpace();
229: if ((c = *lptr) == 0) {i = tEOL; goto EXIT;}
230: lptr++;
231:
232: if (c == ';') {i = tEOC; goto EXIT;}
233: if (c == ',') {i = tDLM; goto EXIT;}
234: if (c == '#') {i = tSIZ; goto EXIT;}
235: if (c == '.') {i = tEOD; goto EXIT;}
236: if (c == '^') {i = tUP; goto EXIT;}
237: if (c == '+') {i = tOPADD; goto EXIT;}
238: if (c == '-') {i = tOPSUB; goto EXIT;}
239: if (c == '*') {i = tOPMUL; goto EXIT;}
240: if (c == '/') {i = tOPDIV; goto EXIT;}
241: if (c == '&') {i = tOPIND; goto EXIT;}
242:
243: if (c == '"') {
244: for (tokenStr = lptr; (c = *lptr) && c != '"'; lptr++);
245: tokenLen = lptr - tokenStr;
246: if (c) lptr++;
247: i = tSTR;
248: goto EXIT;
249: }
250:
251: if (*lptr == '\'') {
252: if (c == 'Q' || c == 'q') {base = 8; goto NUMVAL;}
253: if (c == 'B' || c == 'b') {base = 2; goto NUMVAL;}
254: if (c == 'D' || c == 'd') {base = 10;
255: NUMVAL:
256: while ((c = *++lptr) >= '0' && c < base + '0')
257: tokenVal = tokenVal * base + c - '0';
258: goto NUMEXIT;
259: }
260: if (c == 'H' || c == 'h') goto HEXVAL;
261: }
262:
263: if (isNum(c)) {
264: if (c != '0' || (*lptr != 'x' && *lptr != 'X')) {
265: lptr -= 2;
266: if (defbase == DB10) {base = 10; goto NUMVAL;}
267: }
268: goto HEXVAL;
269: }
270:
271: if (c == '\'') {
272: lptr--;
273: HEXVAL:
274: lptr++;
275: tokenVal = getHexVal(&lptr);
276: c = *lptr;
277: NUMEXIT:
278:
279: i = (isSym(c) || isNum(c)) ? tERNUM : tNUM;
280: goto EXIT;
281: }
282:
283: if (isSym(c)) {
284: tokenStr = --lptr;
285: for (i = 0; isSym(c) || isNum(c) || isExtSym(c); c = *++lptr) {
286:
287: if (i < L_SYMBOL) {
288: if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
289: tokenSym[i++] = c;
290: }
291: }
292:
293: while (i < L_SYMBOL) tokenSym[i++] = ' ';
294:
295: tokenLen = lptr - tokenStr;
296: i = tSYM;
297: goto EXIT;
298: }
299:
300: i = tERCH;
301: EXIT:
302: return token = i;
303: }
304: 305: 306:
307: LOCAL W isnotEOC(void)
308: {
309: if (token <= tEOC) return 0;
310: return_er(E_PAR);
311: }
312: 313: 314:
315: LOCAL W isDLM(void)
316: {
317: if (token == tDLM) {getToken(0); return 1;}
318: return 0;
319: }
320: 321: 322:
323: LOCAL W isnotDLM(void)
324: {
325: if (isDLM()) return 0;
326: return_er(E_LESS);
327: }
328: 329: 330: 331: 332:
333: LOCAL W getNumber(W defbase, W *val)
334: {
335: W op, v;
336: UB *p;
337:
338:
339: if ((op = token) == tOPADD || op == tOPSUB) getToken(defbase);
340:
341: for (*val = 0; ;) {
342: if (token == tSYM) {
343: if ((v = searchRegister(tokenSym, 0)) >= 0) {
344: tokenVal = getRegister(v);
345: } else {
346: if (tokenSym[L_SYMBOL - 1] != ' ') break;
347: p = tokenSym;
348: tokenVal = getHexVal(&p);
349: if (*p != ' ') break;
350: }
351: } else if (token != tNUM) {
352: return_er(E_LESS);
353: }
354:
355:
356: if (op == tOPADD) *val += tokenVal;
357: else if (op == tOPSUB) *val -= tokenVal;
358: else if (op == tOPMUL) *val *= tokenVal;
359: else if (op == tOPDIV) *val /= tokenVal;
360: else *val = tokenVal;
361:
362:
363: while (getToken(defbase) == tOPIND) {
364: if (readMem(*val, &v, 4, 4) != 4) return_er(E_MACV);
365: *val = v;
366: }
367:
368:
369: if (token < tOPADD || token > tOPDIV) break;
370: op = token;
371: getToken(defbase);
372: }
373: if (token > tDLM) return_er(E_LESS);
374: return 0;
375: }
376: 377: 378: 379: 380: 381: 382: 383: 384: 385:
386: LOCAL W getAddrRange(W unit, W flg, W defsz)
387: {
388: W sizeflg;
389:
390:
391: if (token > tDLM) {
392: if (getNumber(0, &cAddr)) return E_LESS;
393: } else {
394: if (flg & 0x01) return_er(E_LESS);
395: }
396:
397:
398: cAddr = ALIGN_L(cAddr, unit);
399:
400:
401: cLen = defsz;
402: if (token == tDLM) {
403: sizeflg = 0;
404: if (getToken(0) == tSIZ) {
405: getToken(0);
406: sizeflg++;
407: }
408: if (getNumber(0, (UW*)&cLen)) return E_LESS;
409: if (sizeflg == 0) {
410: if ((UW)cLen >= cAddr || (UW)cLen >= IMPLICIT_SIZE)
411:
412: cLen = ((W)((UW)cLen - cAddr) + unit) / unit;
413: }
414: cLen *= unit;
415: } else {
416: if (flg & 0x02) return_er(E_LESS);
417: }
418:
419:
420: if (cLen <= 0 || cLen > MAX_RANGE) return_er(E_RANGE);
421: if (((cLen + cAddr - 1) ^ cAddr) & 0x80000000) {
422: cLen = (0x80000000 - (cAddr & 0x7fffffff)) / unit;
423: if ((cLen *= unit) == 0) return_er(E_RANGE);
424: }
425: return 0;
426: }
427: 428: 429: 430: 431:
432: LOCAL W getSetData(UB *buf, W unit)
433: {
434: W n, k;
435: UW num;
436:
437: for (n = 0; ;) {
438: if (token == tSTR) {
439: if (tokenLen == 0) return_er(E_EMPTY);
440:
441:
442: k = ALIGN_U(tokenLen, unit);
443: if (n + k > SETDT_SZ) return_er(E_LIMIT);
444: memcpy(&buf[n], tokenStr, tokenLen);
445: n += tokenLen;
446: if ((k -= tokenLen) > 0) memset(&buf[n], 0, k);
447: n += k;
448: getToken(0);
449: } else {
450: if (n + unit > SETDT_SZ) return_er(E_LIMIT);
451: if (getNumber(0, &num)) return E_LESS;
452: switch (unit) {
453: case 4: *((UW*)&buf[n]) = (UW)num; break;
454: case 2: *((UH*)&buf[n]) = (UH)num; break;
455: default: buf[n] = (UB)num;
456: }
457: n += unit;
458: }
459: if (token <= tEOC) break;
460: if (isnotDLM()) return E_LESS;
461: }
462: if (n == 0) return_er(E_EMPTY);
463: return n;
464: }
465: 466: 467:
468: LOCAL W reaMemory(UW addr, void *dt, W len, W unit)
469: {
470: W n;
471:
472: if ((n = readMem(addr, dt, len, unit)) == len) return 0;
473: DSP_F3(S,"ERR: Memory Read at H'", 08X,(addr+n), CH,'\n');
474: return -1;
475: }
476: 477: 478:
479: LOCAL W wriMemory(UW addr, void *dt, W len, W unit)
480: {
481: W n;
482:
483: if ((n = writeMem(addr, dt, len, unit)) == len) return 0;
484: DSP_F3(S,"ERR: Memory Write at H'", 08X,(addr+n), CH,'\n');
485: return -1;
486: }
487: 488: 489:
490: LOCAL void dspMemory(void *p, W unit)
491: {
492: switch (unit) {
493: case 4: DSP_F2(08X,*((UW*)p), CH,' '); break;
494: case 2: DSP_F2(04X,*((UH*)p), CH,' '); break;
495: default: DSP_F2(02X,*((UB*)p), CH,' ');
496: }
497: }
498: 499: 500: 501: 502: 503: 504: 505:
506: LOCAL void cmdDump(W unit)
507: {
508: W i, n, k;
509: UB *cp, *ep;
510:
511:
512: cAddr = dAddr;
513: if (getAddrRange(unit, 0x00, DEF_MEM_SIZE) || isnotEOC()) return;
514:
515:
516: ep = cp = wrkBuf;
517: for (dAddr = cAddr, i = 0; i < cLen;) {
518:
519: if ((i % 16) == 0) DSP_F2(08X,dAddr, S,": ");
520:
521:
522: if (cp >= ep) {
523: if ((n = cLen - i) > WRKBUF_SZ) n = WRKBUF_SZ;
524: k = readMem(dAddr, cp = wrkBuf, n, unit);
525: if (n != k) {
526: errcode = E_MACV;
527: cLen = i + k;
528: }
529: ep = cp + k;
530: }
531:
532: if (i < cLen) {
533: dspMemory(cp, unit);
534: cp += unit;
535: dAddr += unit;
536: i += unit;
537: }
538:
539: if ((n = i % 16) == 0 || i >= cLen) {
540: k = 16 - n;
541: if (n) {
542: n = k / unit * (unit * 2 + 1);
543: while (n-- > 0) DSP_CH(' ');
544: }
545: k = (i % 16) ? (i % 16) : 16;
546: for (cp -= k; cAddr < dAddr; cAddr++) {
547: n = *cp++;
548: DSP_CH((n >= ' ' && n < 0x7f) ? n : '.');
549: }
550: DSP_LF;
551: }
552: if (checkAbort()) {DSP_LF; break;}
553: }
554: }
555: 556: 557: 558: 559: 560: 561: 562:
563: LOCAL void cmdModify(W unit)
564: {
565: W n;
566: UB buf[4];
567: UB svbuf[L_LINE];
568: UB *svlptr, svtoken;
569: UB dt[SETDT_SZ];
570:
571:
572: cAddr = mAddr;
573: if (token > tDLM && getNumber(0, &cAddr)) return;
574:
575:
576: cAddr = ALIGN_L(cAddr, unit);
577:
578: if (token <= tEOC) {
579:
580: memcpy(svbuf, lineBuf, L_LINE);
581: svlptr = lptr;
582: svtoken = token;
583:
584: for (;;) {
585: DSP_F2(08X,cAddr, S,": ");
586: if (reaMemory(cAddr, buf, unit, unit)) break;
587: dspMemory(buf, unit);
588:
589: if (getLine("-> ") < 0) break;
590: if (getToken(0) == tEOD) break;
591: if (token <= tEOC) cAddr += unit;
592: else if (token == tUP) cAddr -= unit;
593: else if ((n = getSetData(dt, unit)) < 0) break;
594: else {
595: if (wriMemory(cAddr, dt, n, unit)) break;
596: cAddr += n;
597: }
598: }
599:
600: memcpy(lineBuf, svbuf, L_LINE);
601: lptr = svlptr;
602: token = svtoken;
603: if (errcode == E_LESS) errcode = E_PAR;
604:
605: } else if (! isnotDLM()) {
606: if ((n = getSetData(dt, unit)) > 0) {
607: if (wriMemory(cAddr, dt, n, unit) == 0) cAddr += n;
608: }
609: }
610: mAddr = cAddr;
611: }
612: 613: 614: 615: 616: 617: 618: 619:
620: LOCAL void cmdFill(W unit)
621: {
622: W n;
623: UB dt[SETDT_SZ];
624:
625:
626: if (getAddrRange(unit, 0x03, DEF_MEM_SIZE)) return;
627:
628:
629: if (token <= tEOC) {
630: *((UW*)&dt[0]) = 0;
631: n = unit;
632: } else {
633: if (isnotDLM()) return;
634: if ((n = getSetData(dt, unit)) < 0) return;
635: }
636:
637:
638: if (n == unit) {
639: wriMemory(cAddr, dt, cLen, unit | 0x10);
640: } else {
641: for (; cLen > 0; cLen -= n, cAddr += n) {
642: if (n > cLen) n = cLen;
643: if (wriMemory(cAddr, dt, n, unit)) break;
644: }
645: }
646: }
647: 648: 649: 650: 651: 652: 653: 654:
655: LOCAL void cmdSearch(W unit)
656: {
657: W n, len, cnt, ofs;
658: UB *cp, *ep;
659: UB dt[SETDT_SZ];
660:
661:
662: if (getAddrRange(unit, 0x01, DEF_MEM_SIZE) || isnotDLM()) return;
663:
664:
665: if ((len = getSetData(dt, unit)) < 0) return;
666:
667: ep = cp = wrkBuf;
668: for (ofs = cnt = 0; ; ) {
669:
670: if (cp >= ep) {
671: if ((n = WRKBUF_SZ - ofs) > cLen) n = cLen;
672: if (ofs + n < len) break;
673: if (reaMemory(cAddr, &wrkBuf[ofs], n, unit)) break;
674: cAddr += n;
675: cLen -= n;
676: ep = (cp = wrkBuf) + ofs + n;
677: }
678:
679: for ( ; cp < ep && *cp != dt[0]; cp += unit);
680: if ((ofs = ep - cp) < len) {
681:
682: if (ofs > 0) memcpy(wrkBuf, ep = cp, ofs);
683: continue;
684: }
685:
686: if (memcmp(cp, dt, len) == 0) {
687: if (++cnt > MAX_DSP_CNT) {
688: DSP_S("..More..\n");
689: break;
690: }
691: DSP_F2(08X,(cAddr - (ep - cp)), S,":\n");
692: }
693:
694: cp += unit;
695: ofs = 0;
696: if (checkAbort()) break;
697: }
698: }
699: 700: 701: 702: 703: 704:
705: LOCAL void cmdCmpMov(W mov)
706: {
707: UW dst;
708: W i, n, cnt;
709: #define BFSZ (WRKBUF_SZ / 2)
710:
711:
712: if (getAddrRange(1, 0x01, DEF_MEM_SIZE) || isnotDLM()) return;
713:
714:
715: if (getNumber(0, &dst) || isnotEOC()) return;
716:
717: if (mov) {
718: for (; (n = cLen) > 0 && checkAbort() == 0;
719: cAddr += n, dst += n, cLen -= n) {
720: if (n > WRKBUF_SZ) n = WRKBUF_SZ;
721: if (reaMemory(cAddr, wrkBuf, n, 1)) break;
722: if (wriMemory(dst, wrkBuf, n, 1)) break;
723: }
724:
725: } else {
726: for (cnt = 0; (n = cLen) > 0 && checkAbort() == 0;
727: cAddr += n, dst += n, cLen -= n) {
728: if (n > BFSZ) n = BFSZ;
729: if (reaMemory(cAddr, wrkBuf, n, 1)) break;
730: if (reaMemory(dst, &wrkBuf[BFSZ], n, 1)) break;
731: if (memcmp(wrkBuf, &wrkBuf[BFSZ], n) == 0) continue;
732: for (i = 0; i < n; i++) {
733: if (wrkBuf[i] == wrkBuf[BFSZ + i]) continue;
734: if (++cnt > MAX_DSP_CNT) {
735: DSP_S("..More..\n");
736: cLen = 0;
737: break;
738: }
739: DSP_F4(08X,(cAddr + i), S,": ",
740: 02X,wrkBuf[i], S," -> ");
741: DSP_F4(08X,(dst + i), S,": ",
742: 02X,(wrkBuf[BFSZ + i]), CH,'\n');
743: }
744: }
745: }
746: }
747: 748: 749: 750: 751: 752:
753: LOCAL void cmdIO(W unit)
754: {
755: UW port, data;
756: UB *dir;
757:
758:
759: if (getNumber(0, &port)) return;
760:
761: if (unit & 0x10) {
762: if (!isDLM()) er_return(E_LESS);
763: if (getNumber(0, &data) || isnotEOC()) return;
764: if (writeIO(port, data, unit &= 0x0f) == 0) er_return(E_MACV);
765: dir = "<--";
766: } else {
767: if (isnotEOC()) return;
768: if (readIO(port, &data, unit) == 0) er_return(E_MACV);
769: dir = "-->";
770: }
771:
772: DSP_F2(S,"Port ", 08X,port);
773: switch (unit) {
774: case 4: DSP_F5(S,":W ", S,dir, CH,' ', 08X,(UW)data, CH,'\n');
775: break;
776: case 2: DSP_F5(S,":H ", S,dir, CH,' ', 04X,(UH)data, CH,'\n');
777: break;
778: default:DSP_F5(S,":B ", S,dir, CH,' ', 02X,(UB)data, CH,'\n');
779: break;
780: }
781: }
782: 783: 784: 785: 786:
787: LOCAL void cmdDisasm(void)
788: {
789: er_return(E_NOSPT);
790: }
791: 792: 793: 794: 795:
796: LOCAL void cmdRegister(void)
797: {
798: W rno;
799: UW num;
800:
801: if (token <= tEOC) {
802: dispRegister(-1);
803:
804: } else {
805: if (token != tSYM || (rno = searchRegister(tokenSym, 1)) < 0)
806: er_return(E_ILREG);
807:
808: if (getToken(0) <= tEOC) {
809: dispRegister(rno);
810:
811: } else if (!isnotDLM() && !getNumber(0, &num)) {
812: if (!isnotEOC())
813: er_return(setRegister(rno, num));
814: }
815:
816:
817: }
818: }
819: 820: 821: 822: 823: 824:
825: LOCAL void cmdGoTrace(W trace)
826: {
827: UW pc, par;
828:
829:
830: pc = getCurPC();
831: if (token > tDLM && getNumber(0, &pc)) return;
832: if (invalidPC(pc)) er_return(E_PC);
833:
834:
835: par = 0;
836: if (isDLM()) {
837: if (getNumber(0, &par)) return;
838: if (trace == 0 && invalidPC(par)) er_return(E_MACV);
839: }
840: if (isnotEOC()) return;
841:
842: if (trace && par <= 0) par = 1;
843:
844:
845: errcode = goTrace(trace, pc, par);
846: if (errcode >= E_OK) errcode = CMD_FINISH;
847: }
848: 849: 850: 851: 852:
853: LOCAL void cmdBreak(VOID)
854: {
855: UW addr;
856: W atr, cmdlen;
857: UB *cmd;
858:
859: if (token <= tEOC) {
860: dspBreak();
861: return;
862: }
863:
864:
865: if (getNumber(0, &addr)) return;
866:
867:
868: atr = cmdlen = 0;
869: cmd = NULL;
870: while (token == tDLM) {
871:
872: symExt[0] = '+'; symExt[1] = ':';
873: getToken(0);
874: symExt[0] = symExt[1] = '\0';
875: if (token == tSYM) {
876: if (atr) break;
877: if ((atr = getBreakAtr(tokenSym)) < 0)
878: er_return(E_BPATR);
879: } else if (token == tSTR) {
880: if (cmdlen) break;
881: if ((cmdlen = tokenLen) > L_BPCMD) er_return(E_BPCMD);
882: cmd = tokenStr;
883: }
884: getToken(0);
885: }
886:
887:
888: if (! isnotEOC()) {
889: if ((atr = setBreak(addr, atr, cmd, cmdlen))) er_return(atr);
890: }
891: }
892: 893: 894: 895: 896:
897: LOCAL void cmdBrkClr(void)
898: {
899: UW addr;
900:
901: if (token <= tEOC) {
902: clearBreak(0);
903: } else {
904: do {
905: if (getNumber(0, &addr)) return;
906: if (clearBreak(addr) < 0) er_return(E_BPUDF);
907: } while (isDLM());
908: isnotEOC();
909: }
910: }
911: 912: 913: 914: 915:
916: LOCAL void cmdLoad(void)
917: {
918: W i, par;
919: UW addr;
920: LOCAL const struct {
921: UB nm[2];
922: UH par;
923: } proto[] = {
924: {"S ", P_TEXT | P_SFORM},
925: {"XS", P_XMODEM | P_SFORM},
926: {"XM", P_XMODEM | P_MEMIMG},
927: {" ", 0x00}
928: };
929:
930:
931: if (token != tSYM) er_return(E_LESS);
932:
933: par = 0;
934: if (tokenSym[2] == ' ') {
935: for (i = 0; proto[i].par != 0; i++) {
936: if (*((UH*)tokenSym) == *((UH*)proto[i].nm)) {
937: par = proto[i].par;
938: break;
939: }
940: }
941: }
942: if (par == 0) er_return(E_PROTO);
943:
944:
945: getToken(0);
946: if (isDLM()) {
947: if (getNumber(0, &addr)) return;
948: } else {
949: addr = 0;
950: if (par & P_MEMIMG) er_return(E_NOADDR);
951: }
952: if (isnotEOC()) return;
953:
954:
955: errcode = doLoading(par, addr, NULL);
956: }
957: 958: 959: 960: 961:
962: LOCAL void cmdBackTrace(void)
963: {
964: er_return(E_NOSPT);
965: }
966: 967: 968: 969: 970: 971: 972: 973:
974: LOCAL void cmdDisk(W kind)
975: {
976: W i;
977: UW par[3], blksz, nblks;
978: UB c, devnm[L_DEVNM + 1];
979:
980:
981: if (token <= tEOC) {
982: if (kind != 3) er_return(E_LESS);
983: devnm[0] = '\0';
984: } else {
985: if (token != tSYM || tokenLen > L_DEVNM) er_return(E_LESS);
986:
987: for (i = 0; i < tokenLen; i++) {
988: c = tokenSym[i];
989: if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
990: devnm[i] = c;
991: }
992: devnm[i] = '\0';
993: getToken(0);
994: }
995:
996:
997: if (kind <= 1) {
998: for (i = 0; i < 3; i++) {
999: if (isnotDLM()) return;
1000: if (getNumber(0, &par[i])) return;
1001: }
1002: }
1003: if (isnotEOC()) return;
1004:
1005: switch(kind) {
1006: case 0:
1007: case 1:
1008: errcode = rwDisk(devnm, par[0], par[1], (void*)par[2], kind);
1009: break;
1010: case 2:
1011: errcode = infoDisk(devnm, &blksz, &nblks);
1012: if (errcode >= E_OK) {
1013: DSP_S(devnm);
1014: DSP_F5(S,": Bytes/block: ", D,blksz,
1015: S," Total blocks: ", D,nblks, CH,'\n');
1016: }
1017: break;
1018: case 3:
1019: errcode = bootDisk(( devnm[0] == '\0' )? NULL: devnm);
1020: if (errcode >= E_OK) errcode = CMD_FINISH;
1021: break;
1022: }
1023: }
1024: 1025: 1026: 1027: 1028:
1029: LOCAL void cmdExit(void)
1030: {
1031: W par;
1032:
1033:
1034: if (token <= tDLM) par = 0;
1035: else if (getNumber(0, &par)) return;
1036:
1037: DSP_S((par < 0) ? "** System Reset\n" : "** System Power Off\n");
1038: waitMsec(100);
1039:
1040: sysExit(par);
1041: }
1042: 1043: 1044: 1045: 1046:
1047: LOCAL void cmdKill(void)
1048: {
1049: if (isnotEOC()) return;
1050: if (isKillValid() == 0) {
1051: killProcReq = 1;
1052: errcode = CMD_FINISH;
1053: }
1054: }
1055: 1056: 1057: 1058: 1059:
1060: LOCAL void cmdWrom(void)
1061: {
1062: UW addr, data;
1063: W nsec;
1064:
1065:
1066: if (getNumber(0, &addr)) return;
1067: if (isnotDLM() || getNumber(0, &data)) return;
1068: if (isnotDLM() || getNumber(0, &nsec)) return;
1069: if (isnotEOC()) return;
1070: errcode = writeFrom(addr, data, nsec, 1);
1071: }
1072: 1073: 1074: 1075: 1076:
1077: LOCAL void cmdFlashLoad(void)
1078: {
1079: W i, proto, mode;
1080: UW addr[3];
1081:
1082: proto = P_TEXT | P_SFORM;
1083: mode = 0;
1084:
1085:
1086: if (token > tEOC) {
1087: if (token != tSYM) er_return(E_PAR);
1088: for (i = 0; i < L_SYMBOL; i++) {
1089: switch(tokenSym[i]) {
1090: case 'X': proto = P_XMODEM | P_SFORM; break;
1091: case 'E': mode = 1; break;
1092: case ' ': i = L_SYMBOL; break;
1093: default: er_return(E_PAR);
1094: }
1095: }
1096: getToken(0);
1097: if (isnotEOC()) return;
1098: }
1099:
1100:
1101: setupFlashLoad(0, addr);
1102: i = addr[1] - addr[0] + 1;
1103: if (mode) {
1104: DSP_S("Fill Loading RAM Area with 0xFF\n");
1105: memset((void*)addr[0], 0xFF, i);
1106: } else {
1107: DSP_S("Copy Flash ROM Image to RAM Area\n");
1108: memcpy((void*)addr[0], (void*)(addr[0] - addr[2]), i);
1109: }
1110: DSP_S("> Load S-Format Data of Flash ROM\n");
1111: errcode = doLoading(proto, 0, addr);
1112: if (errcode < 0) return;
1113:
1114:
1115: setupFlashLoad(-1, addr);
1116: DSP_F5(S,"Writing Flash ROM at ", 08X,addr[0],
1117: S," [", D,addr[2], S," blks] ... wait\n");
1118: errcode = writeFrom(addr[0], addr[1], addr[2], -1);
1119: }
1120: 1121: 1122:
1123: typedef struct {
1124: UB fnm[12];
1125: UB snm[4];
1126: FP func;
1127: W para;
1128: const HELP *help;
1129: } CMDTAB;
1130:
1131: #define IGN_TRACE 0x1000
1132:
1133: LOCAL void cmdHelp(void);
1134:
1135: LOCAL const CMDTAB cmdTab[] = {
1136: {"DUMP ","D ", cmdDump, 1, &helpD },
1137: {"DUMPBYTE ","DB ", cmdDump, 1, &helpDB },
1138: {"DUMPHALF ","DH ", cmdDump, 2, &helpDH },
1139: {"DUMPWORD ","DW ", cmdDump, 4, &helpDW },
1140: {"MODIFY ","M ", cmdModify, 1, &helpM },
1141: {"MODIFYBYTE ","MB ", cmdModify, 1, &helpMB },
1142: {"MODIFYHALF ","MH ", cmdModify, 2, &helpMH },
1143: {"MODIFYWORD ","MW ", cmdModify, 4, &helpMW },
1144: {"FILL ","F ", cmdFill, 1, &helpF },
1145: {"FILLBYTE ","FB ", cmdFill, 1, &helpFB },
1146: {"FILLHALF ","FH ", cmdFill, 2, &helpFH },
1147: {"FILLWORD ","FW ", cmdFill, 4, &helpFW },
1148: {"SEARCH ","SC ", cmdSearch, 1, &helpSC },
1149: {"SEARCHBYTE ","SCB ", cmdSearch, 1, &helpSCB },
1150: {"SEARCHHALF ","SCH ", cmdSearch, 2, &helpSCH },
1151: {"SEARCHWORD ","SCW ", cmdSearch, 4, &helpSCW },
1152: {"COMPARE ","CMP ", cmdCmpMov, 0, &helpCMP },
1153: {"MOVE ","MOV ", cmdCmpMov, 1, &helpMOV },
1154: {"INPUTBYTE ","IB ", cmdIO, 1, &helpIB },
1155: {"INPUTHALF ","IH ", cmdIO, 2, &helpIH },
1156: {"INPUTWORD ","IW ", cmdIO, 4, &helpIW },
1157: {"OUTPUTBYTE ","OB ", cmdIO, 0x11, &helpOB },
1158: {"OUTPUTHALF ","OH ", cmdIO, 0x12, &helpOH },
1159: {"OUTPUTWORD ","OW ", cmdIO, 0x14, &helpOW },
1160: {"DISASSEMBLE ","DA ", cmdDisasm, 0, &helpDA },
1161: {"REGISTER ","R ", cmdRegister, 0, &helpR },
1162: {"BREAKPOINT ","B ", cmdBreak, 0, &helpB },
1163: {"BREAKCLEAR ","BC ", cmdBrkClr, 0, &helpBC },
1164: {"GO ","G ", cmdGoTrace, 0 | IGN_TRACE, &helpG },
1165: {"STEP ","S ", cmdGoTrace, 1 | IGN_TRACE, &helpS },
1166: {"NEXT ","N ", cmdGoTrace, 2 | IGN_TRACE, &helpN },
1167: {"BACKTRACE ","BTR ", cmdBackTrace, 0, &helpBTR },
1168: {"LOAD ","LO ", cmdLoad, 0, &helpLO },
1169: {"READDISK ","RD ", cmdDisk, 0, &helpRD },
1170: {"WRITEDISK ","WD ", cmdDisk, 1, &helpWD },
1171: {"INFODISK ","ID ", cmdDisk, 2, &helpID },
1172: {"BOOTDISK ","BD ", cmdDisk, 3, &helpBD },
1173: {"KILL ","KILL", cmdKill, 0, &helpKILL },
1174: {"WRITEROM ","WROM", cmdWrom, 0, &helpWROM },
1175: {"FLASHLOAD ","FLLO", cmdFlashLoad, 0, &helpFLLO },
1176: {"HELP ","H ", cmdHelp, 0, &helpH },
1177: {"HELP ","? ", cmdHelp, 0, &helpH },
1178: {"EXIT ","EX ", cmdExit, 0, &helpEX },
1179: { }
1180: };
1181: 1182: 1183:
1184: LOCAL W searchCommand(void)
1185: {
1186: W i;
1187:
1188: if (token == tSYM && tokenSym[12] == ' ') {
1189: for (i = 0; cmdTab[i].func != NULL; i++) {
1190: if (memcmp(cmdTab[i].fnm, tokenSym, 12) == 0 ||
1191: (tokenSym[4] == ' ' &&
1192: *((UW*)cmdTab[i].snm) == *((UW*)tokenSym)) )
1193: return i;
1194: }
1195: }
1196: return E_CMD;
1197: }
1198: 1199: 1200: 1201: 1202:
1203: LOCAL void cmdHelp(void)
1204: {
1205: W i;
1206:
1207: i = searchCommand();
1208: printHelp(( i < 0 )? &helpALL: cmdTab[i].help);
1209: }
1210: 1211: 1212: 1213: 1214: 1215: 1216:
1217: EXPORT void procCommand(UB *cmd, W fin)
1218: {
1219: W i, par;
1220:
1221:
1222: if (cmd) {
1223: strcpy(lptr = lineBuf, cmd);
1224: token = tEOC;
1225: } else {
1226: token = tEOL;
1227: fin = 0;
1228: }
1229:
1230:
1231: daAddr = getCurPC();
1232:
1233: for (;;) {
1234:
1235: while (token > tEOC) getToken(0);
1236:
1237:
1238: if (token == tEOL) {
1239: if (fin) break;
1240: if (getLine(PROMPT) <= 0) continue;
1241: }
1242:
1243:
1244: skipSpace();
1245: if (*lptr == '*') {
1246: getToken(0);
1247: continue;
1248: }
1249:
1250: if (getToken(0) <= tEOC) continue;
1251:
1252:
1253: errcode = errinfo = 0;
1254: if ((i = searchCommand()) < 0) {
1255: errcode = E_CMD;
1256: } else {
1257: if (checkAbort()) continue;
1258: par = cmdTab[i].para;
1259:
1260:
1261: if (fin < 0 && (par & IGN_TRACE)) continue;
1262:
1263:
1264: getToken(0);
1265:
1266:
1267: (*(cmdTab[i].func))(par & 0xff);
1268: }
1269: if (errcode == CMD_FINISH) break;
1270:
1271:
1272: if (errcode < 0) dspError();
1273: }
1274: }