YACASL2
Loading...
Searching...
No Matches
exec.c
Go to the documentation of this file.
1#include "exec.h"
2#include "monitor.h"
3
11char *pr2str(WORD pr);
12
17void svcin();
18
23void svcout();
24
30void setfr(WORD adr);
31
39WORD get_r_r1(WORD oprx);
40
48WORD get_x_r2(WORD oprx);
49
58WORD get_adr_x(WORD adr, WORD oprx);
59
68WORD get_val_adr_x(WORD adr, WORD oprx);
69
73static CERR cerr_exec[] = {
74 { 201, "Program Register (PR) - memory overflow" },
75 { 202, "Stack Pointer (SP) - stack overflow" },
76 { 203, "Stack Pointer (SP) - stack underflow" },
77 { 204, "OP in word #1 - not command code" },
78 { 205, "r/r1 in word #1 - not GR" },
79 { 206, "x/r2 in word #1 - not GR" },
80 { 207, "address in word #2 - out of memory" },
81 { 208, "SVC input - memory overflow" },
82 { 209, "SVC output - memory overflow" },
83 { 214, "CPU Clocks - not positive integer" },
84 { 215, "Memory Size - not integer or out of range: 1 - 65536" },
85};
86
90EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false, false};
91
92CLOCK clock_str2clock(const char *str) {
93 long val = str2l_range(str, 1, LONG_MAX, "Clock");
94 if(val > MAX_CLOCKS) {
95 val = MAX_CLOCKS;
96 fprintf(stderr, "Info - %s: Clock frequency exceeds maximum. Set to %ld\n", str, val);
97 }
98 return (CLOCK)val;
99}
100
101char *pr2str(WORD pr)
102{
103 char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
104
105 sprintf(str, "PR:#%04X", pr);
106 return str;
107}
108
109void svcin()
110{
111 char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
112
113 if(fgets(buf, INSIZE, stdin) == NULL) {
114 sys->memory[sys->cpu->gr[1]] = 0x0;
115 sys->memory[sys->cpu->gr[2]] = 0xFFFF;
116 FREE(buf);
117 return;
118 }
119 for(int i = 0; i < INSIZE; i++) {
120 if(!buf[i] || buf[i] == '\n') {
121 break;
122 }
123 if(sys->cpu->gr[1] + i >= execptr->end) {
124 setcerr(208, ""); /* SVC input - memory overflow */
125 break;
126 }
127 sys->memory[sys->cpu->gr[1] + i] = buf[i];
128 sys->memory[sys->cpu->gr[2]] = i + 1;
129 }
130 FREE(buf);
131}
132
133void svcout()
134{
135 int i;
136 WORD w;
137
138 for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) {
139 if(sys->cpu->gr[1] + i >= execptr->end) {
140 setcerr(209, ""); /* SVC output - memory overflow */
141 return;
142 }
143 /* 「JIS X 0201ラテン文字・片仮名用8ビット符号で規定する文字の符号表」
144 に記載された文字と、改行(CR)/タブを表示 */
145 /* それ以外の文字は、「.」で表す */
146 if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) || /* JIS X 0201ラテン文字 */
147 (w >= 0xA0 && w <= 0xFE) || /* JIS X 0201片仮名用8ビット符号 */
148 w == 0xA || w == '\t')
149 {
150 putchar((char)w);
151 } else {
152 putchar('.');
153 }
154 }
155}
156
157void setfr(WORD adr)
158{
159 sys->cpu->fr = 0x0;
160 /* 第15ビットが1のとき、SFは1 */
161 if((adr & 0x8000) == 0x8000) {
162 sys->cpu->fr += SF;
163 }
164 /* 演算結果が0のとき、ZFは1 */
165 if(adr == 0x0) {
166 sys->cpu->fr += ZF;
167 }
168}
169
171{
172 WORD r = 0;
173 char *s = NULL;
174
175 if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
176 setcerr(205, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
177 FREE(s);
178 return 0x0;
179 }
180 return r;
181}
182
184{
185 WORD x = 0;
186 char *s = NULL;
187
188 if((x = (oprx & 0x000F)) > GRSIZE - 1) {
189 setcerr(206, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
190 FREE(s);
191 return 0x0;
192 }
193 return x;
194}
195
197{
198 WORD a = adr;
199 WORD x = get_x_r2(oprx);
200
201 if(x > 0) {
202 a += sys->cpu->gr[x];
203 }
204 return a;
205}
206
208{
209 WORD a = 0;
210 char *s = NULL;
211
212 if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
213 setcerr(207, s = pr2str(sys->cpu->pr + 1)); /* address in word #2 - out of memory */
214 FREE(s);
215 return 0x0;
216 }
217 return sys->memory[a];
218}
219
220/* exec.hで定義された関数群 */
225
226void nop()
227{
228 sys->cpu->pr += getcmdwordlen("NOP", NONE);
229}
230
232{
233 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
234 setfr(sys->cpu->gr[get_r_r1(w[0])] = get_val_adr_x(w[1], w[0]));
235 sys->cpu->pr += getcmdwordlen("LD", R_ADR_X);
236}
237
239{
240 WORD w[] = {sys->memory[sys->cpu->pr]};
241 setfr(sys->cpu->gr[get_r_r1(w[0])] = sys->cpu->gr[get_x_r2(w[0])]);
242 sys->cpu->pr += getcmdwordlen("LD", R1_R2);
243}
244
245void st()
246{
247 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
248 sys->memory[get_adr_x(w[1], w[0])] = sys->cpu->gr[get_r_r1(w[0])];
249 sys->cpu->pr += getcmdwordlen("ST", R_ADR_X);
250}
251
252void lad()
253{
254 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
255 sys->cpu->gr[get_r_r1(w[0])] = get_adr_x(w[1], w[0]);
256 sys->cpu->pr += getcmdwordlen("LAD", R_ADR_X);
257}
258
259void adda(WORD r, WORD val)
260{
261 long tmp;
262
263 sys->cpu->fr = 0x0;
264 /* 引数の値を16ビット符号付整数として加算し、オーバーフローをチェック */
265 assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
266 if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
267 sys->cpu->fr += OF;
268 }
269 /* 加算した結果を、WORD値に戻す */
270 sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
271 if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
272 sys->cpu->fr += SF;
273 } else if(sys->cpu->gr[r] == 0x0) {
274 sys->cpu->fr += ZF;
275 }
276}
277
279{
280 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
281 adda(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
282 sys->cpu->pr += getcmdwordlen("ADDA", R_ADR_X);
283}
284
286{
287 WORD w[] = {sys->memory[sys->cpu->pr]};
288 adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
289 sys->cpu->pr += getcmdwordlen("ADDA", R1_R2);
290}
291
293{
294 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
295 adda(get_r_r1(w[0]), ~(get_val_adr_x(w[1], w[0])) + 1);
296 sys->cpu->pr += getcmdwordlen("SUBA", R_ADR_X);
297}
298
300{
301 WORD w[] = {sys->memory[sys->cpu->pr]};
302 adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
303 sys->cpu->pr += getcmdwordlen("SUBA", R1_R2);
304}
305
306void addl_gr(WORD r, WORD val, bool add)
307{
308 unsigned long o = 0;
309 unsigned long s = 0;
310
311 o = sys->cpu->gr[r];
312 sys->cpu->fr = 0; /* flag initialize */
313
314 if(add == true) {
315 s = o + val;
316 if(s > 0xFFFF) {
317 sys->cpu->fr += OF;
318 }
319 } else {
320 if(o < val) {
321 sys->cpu->fr += OF;
322 }
323 s = o + (~val + 1);
324 if(s > 0xFFFF) {
325 s &= 0xFFFF;
326 }
327 }
328 sys->cpu->gr[r] = (WORD)s;
329
330 if((s & 0x8000) == 0x8000) {
331 sys->cpu->fr += SF;
332 }
333 else if(s == 0x0) {
334 sys->cpu->fr += ZF;
335 }
336}
337
339{
340 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
341 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
342 sys->cpu->pr += getcmdwordlen("ADDL", R_ADR_X);
343}
344
346{
347 WORD w[] = {sys->memory[sys->cpu->pr]};
348 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
349 sys->cpu->pr += getcmdwordlen("ADDL", R1_R2);
350}
351
353{
354 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
355 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
356 sys->cpu->pr += getcmdwordlen("SUBL", R_ADR_X);
357}
358
360{
361 WORD w[] = {sys->memory[sys->cpu->pr]};
362 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
363 sys->cpu->pr += getcmdwordlen("SUBL", R1_R2);
364}
365
367{
368 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
369 setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
370 sys->cpu->pr += getcmdwordlen("AND", R_ADR_X);
371}
372
374{
375 WORD w[] = {sys->memory[sys->cpu->pr]};
376 setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
377 sys->cpu->pr += getcmdwordlen("AND", R1_R2);
378}
379
381{
382 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
383 setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
384 sys->cpu->pr += getcmdwordlen("OR", R_ADR_X);
385}
386
388{
389 WORD w[] = {sys->memory[sys->cpu->pr]};
390 setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
391 sys->cpu->pr += getcmdwordlen("OR", R1_R2);
392}
393
395{
396 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
397 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
398 sys->cpu->pr += getcmdwordlen("XOR", R_ADR_X);
399}
400
402{
403 WORD w[] = {sys->memory[sys->cpu->pr]};
404 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
405 sys->cpu->pr += getcmdwordlen("XOR", R1_R2);
406}
407
408void cpa(WORD r, WORD val)
409{
410 sys->cpu->fr = 0;
411 if((short)sys->cpu->gr[r] < (short)val) {
412 sys->cpu->fr = SF;
413 } else if(sys->cpu->gr[r] == val) {
414 sys->cpu->fr = ZF;
415 }
416}
417
419{
420 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
421 cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
422 sys->cpu->pr += getcmdwordlen("CPA", R_ADR_X);
423}
424
426{
427 WORD w[] = {sys->memory[sys->cpu->pr]};
428 cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
429 sys->cpu->pr += getcmdwordlen("CPA", R1_R2);
430}
431
432void cpl(WORD r, WORD val)
433{
434 sys->cpu->fr = 0x0;
435 if(sys->cpu->gr[r] < val) {
436 sys->cpu->fr = SF;
437 } else if(sys->cpu->gr[r] == val) {
438 sys->cpu->fr = ZF;
439 }
440}
441
443{
444 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
445 cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
446 sys->cpu->pr += getcmdwordlen("CPL", R_ADR_X);
447}
448
450{
451 WORD w[] = {sys->memory[sys->cpu->pr]};
452 cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
453 sys->cpu->pr += getcmdwordlen("CPL", R1_R2);
454}
455
456void sla()
457{
458 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
459 WORD r = get_r_r1(w[0]);
460 WORD sign = sys->cpu->gr[r] & 0x8000;
461 WORD last = 0;
462
463 sys->cpu->fr = 0;
464 sys->cpu->gr[r] &= 0x7FFF;
465 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
466 last = sys->cpu->gr[r] & 0x4000;
467 sys->cpu->gr[r] <<= 1;
468 }
469 sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
470 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
471 if(last > 0x0) {
472 sys->cpu->fr += OF;
473 }
474 /* 符号(第15ビット)が1のとき、SFは1 */
475 if(sign > 0x0) {
476 sys->cpu->fr += SF;
477 }
478 /* 演算結果が0のとき、ZFは1 */
479 if(sys->cpu->gr[r] == 0x0) {
480 sys->cpu->fr += ZF;
481 }
482 sys->cpu->pr += getcmdwordlen("SLA", R_ADR_X);
483}
484
485void sra()
486{
487 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
488 WORD r = get_r_r1(w[0]);
489 WORD sign = sys->cpu->gr[r] & 0x8000;
490 WORD last = 0;
491
492 sys->cpu->fr = 0;
493 sys->cpu->gr[r] &= 0x7FFF;
494 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
495 last = sys->cpu->gr[r] & 0x1;
496 sys->cpu->gr[r] >>= 1;
497 if(sign > 0) {
498 sys->cpu->gr[r] |= 0x4000;
499 }
500 }
501 sys->cpu->gr[r] = sign | sys->cpu->gr[r];
502 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
503 if(last > 0x0) {
504 sys->cpu->fr += OF;
505 }
506 /* 符号(第15ビット)が1のとき、SFは1 */
507 if(sign > 0x0) {
508 sys->cpu->fr += SF;
509 }
510 /* 演算結果が0のとき、ZFは1 */
511 if(sys->cpu->gr[r] == 0x0) {
512 sys->cpu->fr += ZF;
513 }
514 sys->cpu->pr += getcmdwordlen("SRA", R_ADR_X);
515}
516
517void sll()
518{
519 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
520 WORD last = 0;
521 WORD r = get_r_r1(w[0]);
522
523 sys->cpu->fr = 0x0;
524 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
525 last = sys->cpu->gr[r] & 0x8000;
526 sys->cpu->gr[r] <<= 1;
527 }
528 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
529 if(last > 0x0) {
530 sys->cpu->fr += OF;
531 }
532 /* 第15ビットが1のとき、SFは1 */
533 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
534 sys->cpu->fr += SF;
535 }
536 /* 演算結果が0のとき、ZFは1 */
537 if(sys->cpu->gr[r] == 0x0) {
538 sys->cpu->fr += ZF;
539 }
540 sys->cpu->pr += getcmdwordlen("SLL", R_ADR_X);
541}
542
543void srl()
544{
545 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
546 WORD last = 0;
547 WORD r = get_r_r1(w[0]);
548
549 sys->cpu->fr = 0x0;
550 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
551 last = sys->cpu->gr[r] & 0x0001;
552 sys->cpu->gr[r] >>= 1;
553 }
554 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
555 if(last > 0x0) {
556 sys->cpu->fr += OF;
557 }
558 /* 第15ビットが1のとき、SFは1 */
559 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
560 sys->cpu->fr += SF;
561 }
562 /* 演算結果が0のとき、ZFは1 */
563 if(sys->cpu->gr[r] == 0x0) {
564 sys->cpu->fr += ZF;
565 }
566 sys->cpu->pr += getcmdwordlen("SRL", R_ADR_X);
567}
568
569void jmi()
570{
571 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
572 if((sys->cpu->fr & SF) > 0) {
573 sys->cpu->pr = get_adr_x(w[1], w[0]);
574 } else {
575 sys->cpu->pr += getcmdwordlen("JMI", ADR_X);
576 }
577}
578
579void jnz()
580{
581 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
582 if((sys->cpu->fr & ZF) == 0) {
583 sys->cpu->pr = get_adr_x(w[1], w[0]);
584 } else {
585 sys->cpu->pr += getcmdwordlen("JNZ", ADR_X);
586 }
587}
588
589void jze()
590{
591 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
592 if((sys->cpu->fr & ZF) > 0) {
593 sys->cpu->pr = get_adr_x(w[1], w[0]);
594 } else {
595 sys->cpu->pr += getcmdwordlen("JZE", ADR_X);
596 }
597}
598
599void jump()
600{
601 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
602 sys->cpu->pr = get_adr_x(w[1], w[0]);
603}
604
605void jpl()
606{
607 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
608 if((sys->cpu->fr & (SF | ZF)) == 0) {
609 sys->cpu->pr = get_adr_x(w[1], w[0]);
610 } else {
611 sys->cpu->pr += getcmdwordlen("JPL", ADR_X);
612 }
613}
614
615void jov()
616{
617 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
618 if((sys->cpu->fr & OF) > 0) {
619 sys->cpu->pr = get_adr_x(w[1], w[0]);
620 } else {
621 sys->cpu->pr += getcmdwordlen("JOV", ADR_X);
622 }
623}
624
625void push()
626{
627 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
628 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
629 sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
630 sys->cpu->pr += getcmdwordlen("PUSH", ADR_X);
631}
632
633void pop()
634{
635 assert(sys->cpu->sp > execptr->end);
636 WORD w[] = {sys->memory[sys->cpu->pr]};
637 char *s = NULL;
638
639 if(sys->cpu->sp >= sys->memsize) {
640 setcerr(203, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack underflow */
641 FREE(s);
642 } else {
643 sys->cpu->gr[get_r_r1(w[0])] = sys->memory[(sys->cpu->sp)++];
644 sys->cpu->pr += getcmdwordlen("POP", R_);
645 }
646}
647
648void call()
649{
650 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
651 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
652 sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
653 sys->cpu->pr = get_adr_x(w[1], w[0]);
654}
655
656void ret()
657{
658 assert(sys->cpu->sp <= sys->memsize);
659 if(sys->cpu->sp == sys->memsize) {
660 execptr->stop = true;
661 } else if(sys->cpu->sp < sys->memsize) {
662 sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
663 }
664}
665
666void svc()
667{
668 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
669 switch(get_adr_x(w[1], w[0]))
670 {
671 case 0x0: /* STOP */
672 execptr->stop = true;
673 break;
674 case 0x1: /* IN */
675 svcin();
676 break;
677 case 0x2: /* OUT */
678 svcout();
679 break;
680 }
681 sys->cpu->pr += getcmdwordlen("SVC", ADR_X);
682}
683
684void exec()
685{
686 CLOCK clock_begin = 0;
687 CLOCK clock_end = 0;
688 void (*cmdptr)() = NULL;
689 char *s = NULL;
690 const char *monmsg = "COMET II machine code monitor. Type ? for help.\n";
691
692 create_cmdtable(HASH_CODE); /* 命令コードがキーのハッシュ表を作成 */
693
694 /* 機械語の実行 */
695 for (sys->cpu->pr = execptr->start; ; ) {
696 clock_begin = clock(); /* クロック周波数設定のため、実行開始時間を格納 */
698 /* モニターモードでCOMET II起動時、またはステップモードかブレークポイントの場合、モニターを起動 */
699 if((execmode.monitor == true && execptr->started == false) || execptr->stop == true || execmode.step == true || getbps(sys->cpu->pr) == true)
700 {
701 /* モニターモードでCOMET II起動時、フラグを立て、メッセージを表示 */
702 if(execptr->started == false) {
703 execptr->started = true;
704 fprintf(stdout, "%s", monmsg);
705 }
706 monitor();
707 }
708 /* プログラムレジスタをチェック */
709 if(sys->cpu->pr >= sys->memsize) {
710 setcerr(201, s = pr2str(sys->cpu->pr)); /* Program Register (PR) - memory overflow */
711 goto execfin;
712 }
713 /* スタックポインタをチェック */
714 if(sys->cpu->sp <= execptr->end) {
715 setcerr(202, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack overflow */
716 goto execfin;
717 }
718 /* コードから命令を取得 */
719 /* 取得できない場合はエラー終了 */
720 if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
721 setcerr(204, s = pr2str(sys->cpu->pr)); /* OP in word #1 - not command code */
722 goto execfin;
723 }
724 /* 命令の実行 */
725 (*cmdptr)();
726 /* エラー発生時はエラー終了 */
727 if(cerr->num > 0) {
728 goto execfin;
729 }
730 /* 終了フラグがtrueの場合は、モニターまたは正常終了 */
731 if(execptr->stop == true) {
732 if(execmode.monitor == true) {
733 fprintf(stdout, "Return to top.\n");
734 } else {
735 break;
736 }
737 }
738 /* クロック周波数の設定 */
739 do {
740 clock_end = clock();
741 } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
742 }
743execfin:
744 FREE(s);
745 freebps();
746 free_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を解放 */
747 if(cerr->num > 0) {
748 fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);
749 }
750}
CERR * cerr
現在のエラー
Definition cerr.c:10
@ CERRSTRSIZE
Definition cerr.h:38
struct _CERR CERR
エラーを表すデータ型
void addcerrlist(int cerrc, CERR cerrv[])
エラーリストを作成・追加する
Definition cerr.c:14
void setcerr(int num, const char *str)
現在のエラーを設定する
Definition cerr.c:46
#define FREE(ptr)
メモリを解放するマクロ
Definition cmem.h:22
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition cmem.c:23
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition cmem.h:15
long str2l_range(const char *str, long min, long max, const char *name)
数値文字列が特定の範囲の数値かチェックし、正の場合は変換した数値、不正の場合は0を返す
Definition cmem.c:3
void exec()
COMET II仮想マシンを実行する
Definition exec.c:684
void and_r_adr_x()
AND命令 - オペランドr,adr,x。語長2.
Definition exec.c:366
void st()
ST命令。語長2.
Definition exec.c:245
void svcin()
標準入力から文字データを読込(SVC 1)
Definition exec.c:109
void jmi()
JMI命令。語長2.
Definition exec.c:569
void svc()
SVC命令。語長2.
Definition exec.c:666
void suba_r1_r2()
SUBA命令 - オペランドr1,r2。語長1.
Definition exec.c:299
void cpl(WORD r, WORD val)
Definition exec.c:432
void cpl_r_adr_x()
CPL命令 - オペランドr,adr,x。語長2.
Definition exec.c:442
void sra()
SRA命令 - オペランドr,adr,x。語長2.
Definition exec.c:485
void pop()
POP命令。語長1.
Definition exec.c:633
void adda(WORD r, WORD val)
Definition exec.c:259
void svcout()
標準出力へ文字データを書出(SVC 2)
Definition exec.c:133
void adda_r1_r2()
ADDA命令 - オペランドr1,r2。語長1.
Definition exec.c:285
CLOCK clock_str2clock(const char *str)
クロック周波数を表す数値文字列を、正の整数値であるCLOCK型の数値に変換。変換できない場合は、エラーを表示して0を返す
Definition exec.c:92
void xor_r1_r2()
XOR命令 - オペランドr1,r2。語長1.
Definition exec.c:401
void subl_r_adr_x()
SUBL命令 - オペランドr,adr,x。語長2.
Definition exec.c:352
void sla()
SLA命令 - オペランドr,adr,x。語長2.
Definition exec.c:456
WORD get_val_adr_x(WORD adr, WORD oprx)
2つのWORD値からadr[,x]のアドレスに格納されている値を取得
Definition exec.c:207
char * pr2str(WORD pr)
プログラムレジスタ(PR)を表すWORD値を文字列に変換
Definition exec.c:101
void srl()
SRL命令 - オペランドr,adr,x。語長2.
Definition exec.c:543
WORD get_adr_x(WORD adr, WORD oprx)
2つのWORD値からadr[,x]を取得
Definition exec.c:196
WORD get_x_r2(WORD oprx)
WORD値からx/r2を取得
Definition exec.c:183
void ld_r_adr_x()
LD命令 - オペランドr,adr,x。語長2.
Definition exec.c:231
void jnz()
JNZ命令。語長2.
Definition exec.c:579
void adda_r_adr_x()
ADDA命令 - オペランドr,adr,x。語長2.
Definition exec.c:278
void addl_r1_r2()
ADDL命令 - オペランドr1,r2。語長1.
Definition exec.c:345
void cpl_r1_r2()
CPL命令 - オペランドr1,r2。語長1.
Definition exec.c:449
WORD get_r_r1(WORD oprx)
WORD値からr/r1を取得
Definition exec.c:170
void jump()
JUMP命令。語長2.
Definition exec.c:599
void subl_r1_r2()
SUBL命令 - オペランドr1,r2。語長1.
Definition exec.c:359
void cpa_r1_r2()
CPA命令 - オペランドr1,r2。語長1.
Definition exec.c:425
void addl_gr(WORD r, WORD val, bool add)
Definition exec.c:306
void push()
PUSH命令。語長2.
Definition exec.c:625
void cpa(WORD r, WORD val)
Definition exec.c:408
void nop()
NOP命令。語長1(OPのみ)
Definition exec.c:226
void cpa_r_adr_x()
CPA命令 - オペランドr,adr,x。語長2.
Definition exec.c:418
void and_r1_r2()
AND命令 - オペランドr1,r2。語長1.
Definition exec.c:373
void addcerrlist_exec()
実行エラーをエラーリストに追加する
Definition exec.c:221
void ret()
RET命令。語長1(OPのみ)
Definition exec.c:656
void or_r_adr_x()
OR命令 - オペランドr,adr,x。語長2.
Definition exec.c:380
void suba_r_adr_x()
SUBA命令 - オペランドr,adr,x。語長2.
Definition exec.c:292
static CERR cerr_exec[]
実行エラーの定義
Definition exec.c:73
void addl_r_adr_x()
ADDL命令 - オペランドr,adr,x。語長2.
Definition exec.c:338
void sll()
SLL命令 - オペランドr,adr,x。語長2.
Definition exec.c:517
void call()
CALL命令。語長2.
Definition exec.c:648
void jpl()
JPL命令。語長2.
Definition exec.c:605
void lad()
LAD命令。語長2.
Definition exec.c:252
void setfr(WORD adr)
ロード/論理積/論理和/排他的論理和のフラグ設定。OFは常に0
Definition exec.c:157
void xor_r_adr_x()
XOR命令 - オペランドr,adr,x。語長2.
Definition exec.c:394
void jze()
JZE命令。語長2.
Definition exec.c:589
void or_r1_r2()
OR命令 - オペランドr1,r2。語長1.
Definition exec.c:387
void jov()
JOV命令。語長2.
Definition exec.c:615
void ld_r1_r2()
LD命令 - オペランドr1,r2。語長1.
Definition exec.c:238
@ INSIZE
Definition exec.h:14
void dsp_trace_dump()
COMET IIのレジスタとメモリを実行状況と設定に応じて表示する
Definition dump.c:61
void monitor()
COMET IIモニターを起動する
Definition monitor.c:386
bool getbps(WORD adr)
ブレークポイント表にアドレスがある場合はtrue、ない場合はfalseを返す
Definition monitor.c:29
void freebps()
ブレークポイント表を解放する
Definition monitor.c:120
@ HASH_CODE
Definition struct.h:65
@ GRSIZE
Definition struct.h:19
@ MAX_CLOCKS
Definition struct.h:22
EXECPTR * execptr
Definition struct.c:13
bool create_cmdtable(CMDTAB_HASH hash)
命令ハッシュ表を作成する
Definition struct.c:124
@ OF
Definition struct.h:30
@ ZF
Definition struct.h:32
@ SF
Definition struct.h:31
void * getcmdptr(WORD code)
Definition struct.c:218
unsigned int CLOCK
Definition struct.h:12
@ R_
Definition struct.h:97
@ R_ADR_X
Definition struct.h:80
@ ADR_X
Definition struct.h:92
@ NONE
Definition struct.h:101
@ R1_R2
Definition struct.h:86
void free_cmdtable(CMDTAB_HASH hash)
Definition struct.c:146
SYSTEM * sys
COMET IIの仮想実行マシンシステム
Definition struct.c:8
WORD getcmdwordlen(const char *cmd, CMDTYPE type)
Definition struct.c:183
EXECMODE execmode
実行モード: trace, logical, dump, reverse, monitor, step
Definition exec.c:90
実行モードを表すデータ型
Definition struct.h:146
unsigned short WORD
16ビットの数値を表すデータ型
Definition word.h:9