This source file includes following definitions.
- pr2str
- svcin
- svcout
- setfr
- get_r_r1
- get_x_r2
- get_adr_x
- get_val_adr_x
- addcerrlist_exec
- nop
- ld_r_adr_x
- ld_r1_r2
- st
- lad
- adda
- adda_r_adr_x
- adda_r1_r2
- suba_r_adr_x
- suba_r1_r2
- addl_gr
- addl_r_adr_x
- addl_r1_r2
- subl_r_adr_x
- subl_r1_r2
- and_r_adr_x
- and_r1_r2
- or_r_adr_x
- or_r1_r2
- xor_r_adr_x
- xor_r1_r2
- cpa
- cpa_r_adr_x
- cpa_r1_r2
- cpl
- cpl_r_adr_x
- cpl_r1_r2
- sla
- sra
- sll
- srl
- jpl
- jmi
- jnz
- jze
- jov
- jump
- push
- pop
- call
- ret
- svc
- exec
1 #include "exec.h"
2
3
4
5
6
7
8
9
10 char *pr2str(WORD pr);
11
12
13
14
15
16
17 void svcin();
18
19
20
21
22
23
24 void svcout();
25
26
27
28
29
30
31
32
33 void setfr(WORD adr);
34
35
36
37
38
39
40
41
42 WORD get_r_r1(WORD oprx);
43
44
45
46
47
48
49
50
51 WORD get_x_r2(WORD oprx);
52
53
54
55
56
57
58
59
60
61 WORD get_adr_x(WORD adr, WORD oprx);
62
63
64
65
66
67
68
69
70
71 WORD get_val_adr_x(WORD adr, WORD oprx);
72
73
74
75
76 static CERR cerr_exec[] = {
77 { 201, "Program Register (PR) - memory overflow" },
78 { 202, "Stack Pointer (SP) - stack overflow" },
79 { 203, "Stack Pointer (SP) - stack underflow" },
80 { 204, "OP in word #1 - not command code" },
81 { 205, "r/r1 in word #1 - not GR" },
82 { 206, "x/r2 in word #1 - not GR" },
83 { 207, "address in word #2 - out of memory" },
84 { 208, "SVC input - memory overflow" },
85 { 209, "SVC output - memory overflow" },
86 };
87
88
89
90
91 EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false};
92
93 char *pr2str(WORD pr)
94 {
95 char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
96
97 sprintf(str, "PR:#%04X", pr);
98 return str;
99 }
100
101 void svcin()
102 {
103 int i;
104 char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
105
106 if(fgets(buf, INSIZE, stdin) == NULL) {
107 sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0;
108 return;
109 }
110 for(i = 0; i < INSIZE; i++) {
111 if(!buf[i] || buf[i] == '\n') {
112 --i;
113 break;
114 }
115 if(sys->cpu->gr[1] + i > execptr->end) {
116 setcerr(208, "");
117 break;
118 }
119 sys->memory[sys->cpu->gr[1] + i] = buf[i];
120 }
121 sys->memory[sys->cpu->gr[2]] = i + 1;
122 FREE(buf);
123 }
124
125 void svcout()
126 {
127 int i;
128 WORD w;
129
130 for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) {
131 if(sys->cpu->gr[1] + i > execptr->end) {
132 setcerr(209, "");
133 return;
134 }
135
136
137
138 if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) ||
139 (w >= 0xA0 && w <= 0xFE) ||
140 w == 0xA || w == '\t')
141 {
142 putchar((char)w);
143 } else {
144 putchar('.');
145 }
146 }
147 }
148
149 void setfr(WORD adr)
150 {
151 sys->cpu->fr = 0x0;
152
153 if((adr & 0x8000) == 0x8000) {
154 sys->cpu->fr += SF;
155 }
156
157 if(adr == 0x0) {
158 sys->cpu->fr += ZF;
159 }
160 }
161
162 WORD get_r_r1(WORD oprx)
163 {
164 WORD r = 0;
165 char *s = NULL;
166
167 if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
168 setcerr(205, s = pr2str(sys->cpu->pr));
169 FREE(s);
170 return 0x0;
171 }
172 return r;
173 }
174
175 WORD get_x_r2(WORD oprx)
176 {
177 WORD x = 0;
178 char *s = NULL;
179
180 if((x = (oprx & 0x000F)) > GRSIZE - 1) {
181 setcerr(206, s = pr2str(sys->cpu->pr));
182 FREE(s);
183 return 0x0;
184 }
185 return x;
186 }
187
188 WORD get_adr_x(WORD adr, WORD oprx)
189 {
190 WORD a = adr;
191 WORD x = get_x_r2(oprx);
192
193 if(x > 0) {
194 a += sys->cpu->gr[x];
195 }
196 return a;
197 }
198
199 WORD get_val_adr_x(WORD adr, WORD oprx)
200 {
201 WORD a = 0;
202 char *s = NULL;
203
204 if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
205 setcerr(207, s = pr2str(sys->cpu->pr + 1));
206 FREE(s);
207 return 0x0;
208 }
209 return sys->memory[a];
210 }
211
212
213 void addcerrlist_exec()
214 {
215 addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
216 }
217
218 void nop()
219 {
220 sys->cpu->pr += 1;
221 }
222
223 void ld_r_adr_x()
224 {
225 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
226 setfr(sys->cpu->gr[get_r_r1(w[0])] = get_val_adr_x(w[1], w[0]));
227 sys->cpu->pr += 2;
228 }
229
230 void ld_r1_r2()
231 {
232 WORD w[] = {sys->memory[sys->cpu->pr]};
233 setfr(sys->cpu->gr[get_r_r1(w[0])] = sys->cpu->gr[get_x_r2(w[0])]);
234 sys->cpu->pr += 1;
235 }
236
237 void st()
238 {
239 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
240 sys->memory[get_adr_x(w[1], w[0])] = sys->cpu->gr[get_r_r1(w[0])];
241 sys->cpu->pr += 2;
242 }
243
244 void lad()
245 {
246 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
247 sys->cpu->gr[get_r_r1(w[0])] = get_adr_x(w[1], w[0]);
248 sys->cpu->pr += 2;
249 }
250
251 void adda(WORD r, WORD val)
252 {
253 long tmp;
254
255 sys->cpu->fr = 0x0;
256
257 assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
258 if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
259 sys->cpu->fr += OF;
260 }
261
262 sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
263 if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
264 sys->cpu->fr += SF;
265 } else if(sys->cpu->gr[r] == 0x0) {
266 sys->cpu->fr += ZF;
267 }
268 }
269
270 void adda_r_adr_x()
271 {
272 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
273 adda(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
274 sys->cpu->pr += 2;
275 }
276
277 void adda_r1_r2()
278 {
279 WORD w[] = {sys->memory[sys->cpu->pr]};
280 adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
281 sys->cpu->pr += 1;
282 }
283
284 void suba_r_adr_x()
285 {
286 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
287 adda(get_r_r1(w[0]), ~(get_val_adr_x(w[1], w[0])) + 1);
288 sys->cpu->pr += 2;
289 }
290
291 void suba_r1_r2()
292 {
293 WORD w[] = {sys->memory[sys->cpu->pr]};
294 adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
295 sys->cpu->pr += 1;
296 }
297
298 void addl_gr(WORD r, WORD val, bool add)
299 {
300 unsigned long o = 0;
301 unsigned long s = 0;
302
303 o = sys->cpu->gr[r];
304 sys->cpu->fr = 0;
305
306 if(add == true) {
307 s = o + val;
308 if(s > 0xFFFF) {
309 sys->cpu->fr += OF;
310 }
311 } else {
312 if(o < val) {
313 sys->cpu->fr += OF;
314 }
315 s = o + (~val + 1);
316 if(s > 0xFFFF) {
317 s &= 0xFFFF;
318 }
319 }
320 sys->cpu->gr[r] = (WORD)s;
321
322 if((s & 0x8000) == 0x8000) {
323 sys->cpu->fr += SF;
324 }
325 else if(s == 0x0) {
326 sys->cpu->fr += ZF;
327 }
328 }
329
330 void addl_r_adr_x()
331 {
332 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
333 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
334 sys->cpu->pr += 2;
335 }
336
337 void addl_r1_r2()
338 {
339 WORD w[] = {sys->memory[sys->cpu->pr]};
340 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
341 sys->cpu->pr += 1;
342 }
343
344 void subl_r_adr_x()
345 {
346 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
347 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
348 sys->cpu->pr += 2;
349 }
350
351 void subl_r1_r2()
352 {
353 WORD w[] = {sys->memory[sys->cpu->pr]};
354 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
355 sys->cpu->pr += 1;
356 }
357
358 void and_r_adr_x()
359 {
360 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
361 setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
362 sys->cpu->pr += 2;
363 }
364
365 void and_r1_r2()
366 {
367 WORD w[] = {sys->memory[sys->cpu->pr]};
368 setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
369 sys->cpu->pr += 1;
370 }
371
372 void or_r_adr_x()
373 {
374 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
375 setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
376 sys->cpu->pr += 2;
377 }
378
379 void or_r1_r2()
380 {
381 WORD w[] = {sys->memory[sys->cpu->pr]};
382 setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
383 sys->cpu->pr += 1;
384 }
385
386 void xor_r_adr_x()
387 {
388 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
389 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
390 sys->cpu->pr += 2;
391 }
392
393 void xor_r1_r2()
394 {
395 WORD w[] = {sys->memory[sys->cpu->pr]};
396 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
397 sys->cpu->pr += 1;
398 }
399
400 void cpa(WORD r, WORD val)
401 {
402 sys->cpu->fr = 0;
403 if((short)sys->cpu->gr[r] < (short)val) {
404 sys->cpu->fr = SF;
405 } else if(sys->cpu->gr[r] == val) {
406 sys->cpu->fr = ZF;
407 }
408 }
409
410 void cpa_r_adr_x()
411 {
412 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
413 cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
414 sys->cpu->pr += 2;
415 }
416
417 void cpa_r1_r2()
418 {
419 WORD w[] = {sys->memory[sys->cpu->pr]};
420 cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
421 sys->cpu->pr += 1;
422 }
423
424 void cpl(WORD r, WORD val)
425 {
426 sys->cpu->fr = 0x0;
427 if(sys->cpu->gr[r] < val) {
428 sys->cpu->fr = SF;
429 } else if(sys->cpu->gr[r] == val) {
430 sys->cpu->fr = ZF;
431 }
432 }
433
434 void cpl_r_adr_x()
435 {
436 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
437 cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
438 sys->cpu->pr += 2;
439 }
440
441 void cpl_r1_r2()
442 {
443 WORD w[] = {sys->memory[sys->cpu->pr]};
444 cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
445 sys->cpu->pr += 1;
446 }
447
448 void sla()
449 {
450 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
451 WORD r = get_r_r1(w[0]);
452 WORD sign = sys->cpu->gr[r] & 0x8000;
453 WORD last = 0;
454
455 sys->cpu->fr = 0;
456 sys->cpu->gr[r] &= 0x7FFF;
457 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
458 last = sys->cpu->gr[r] & 0x4000;
459 sys->cpu->gr[r] <<= 1;
460 }
461 sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
462
463 if(last > 0x0) {
464 sys->cpu->fr += OF;
465 }
466
467 if(sign > 0x0) {
468 sys->cpu->fr += SF;
469 }
470
471 if(sys->cpu->gr[r] == 0x0) {
472 sys->cpu->fr += ZF;
473 }
474 sys->cpu->pr += 2;
475 }
476
477 void sra()
478 {
479 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
480 WORD r = get_r_r1(w[0]);
481 WORD sign = sys->cpu->gr[r] & 0x8000;
482 WORD last = 0;
483
484 sys->cpu->fr = 0;
485 sys->cpu->gr[r] &= 0x7FFF;
486 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
487 last = sys->cpu->gr[r] & 0x1;
488 sys->cpu->gr[r] >>= 1;
489 if(sign > 0) {
490 sys->cpu->gr[r] |= 0x4000;
491 }
492 }
493 sys->cpu->gr[r] = sign | sys->cpu->gr[r];
494
495 if(last > 0x0) {
496 sys->cpu->fr += OF;
497 }
498
499 if(sign > 0x0) {
500 sys->cpu->fr += SF;
501 }
502
503 if(sys->cpu->gr[r] == 0x0) {
504 sys->cpu->fr += ZF;
505 }
506 sys->cpu->pr += 2;
507 }
508
509 void sll()
510 {
511 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
512 WORD last = 0;
513 WORD r = get_r_r1(w[0]);
514
515 sys->cpu->fr = 0x0;
516 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
517 last = sys->cpu->gr[r] & 0x8000;
518 sys->cpu->gr[r] <<= 1;
519 }
520
521 if(last > 0x0) {
522 sys->cpu->fr += OF;
523 }
524
525 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
526 sys->cpu->fr += SF;
527 }
528
529 if(sys->cpu->gr[r] == 0x0) {
530 sys->cpu->fr += ZF;
531 }
532 sys->cpu->pr += 2;
533 }
534
535 void srl()
536 {
537 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
538 WORD last = 0;
539 WORD r = get_r_r1(w[0]);
540
541 sys->cpu->fr = 0x0;
542 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
543 last = sys->cpu->gr[r] & 0x0001;
544 sys->cpu->gr[r] >>= 1;
545 }
546
547 if(last > 0x0) {
548 sys->cpu->fr += OF;
549 }
550
551 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
552 sys->cpu->fr += SF;
553 }
554
555 if(sys->cpu->gr[r] == 0x0) {
556 sys->cpu->fr += ZF;
557 }
558 sys->cpu->pr += 2;
559 }
560
561 void jpl()
562 {
563 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
564 if((sys->cpu->fr & (SF | ZF)) == 0) {
565 sys->cpu->pr = get_adr_x(w[1], w[0]);
566 } else {
567 sys->cpu->pr += 2;
568 }
569 }
570
571 void jmi()
572 {
573 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
574 if((sys->cpu->fr & SF) > 0) {
575 sys->cpu->pr = get_adr_x(w[1], w[0]);
576 } else {
577 sys->cpu->pr += 2;
578 }
579 }
580
581 void jnz()
582 {
583 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
584 if((sys->cpu->fr & ZF) == 0) {
585 sys->cpu->pr = get_adr_x(w[1], w[0]);
586 } else {
587 sys->cpu->pr += 2;
588 }
589 }
590
591 void jze()
592 {
593 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
594 if((sys->cpu->fr & ZF) > 0) {
595 sys->cpu->pr = get_adr_x(w[1], w[0]);
596 } else {
597 sys->cpu->pr += 2;
598 }
599 }
600
601 void jov()
602 {
603 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
604 if((sys->cpu->fr & OF) > 0) {
605 sys->cpu->pr = get_adr_x(w[1], w[0]);
606 } else {
607 sys->cpu->pr += 2;
608 }
609 }
610
611 void jump()
612 {
613 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
614 sys->cpu->pr = get_adr_x(w[1], w[0]);
615 }
616
617 void push()
618 {
619 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
620 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
621 sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
622 sys->cpu->pr += 2;
623 }
624
625 void pop()
626 {
627 assert(sys->cpu->sp > execptr->end);
628 WORD w[] = {sys->memory[sys->cpu->pr]};
629 char *s = NULL;
630
631 if(sys->cpu->sp >= sys->memsize) {
632 setcerr(203, s = pr2str(sys->cpu->pr));
633 FREE(s);
634 } else {
635 sys->cpu->gr[get_r_r1(w[0])] = sys->memory[(sys->cpu->sp)++];
636 sys->cpu->pr += 1;
637 }
638 }
639
640 void call()
641 {
642 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
643 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
644 sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
645 sys->cpu->pr = get_adr_x(w[1], w[0]);
646 }
647
648 void ret()
649 {
650 assert(sys->cpu->sp <= sys->memsize);
651 if(sys->cpu->sp == sys->memsize) {
652 execptr->stop = true;
653 } else if(sys->cpu->sp < sys->memsize) {
654 sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
655 }
656 }
657
658 void svc()
659 {
660 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
661 switch(get_adr_x(w[1], w[0]))
662 {
663 case 0x0:
664 execptr->stop = true;
665 break;
666 case 0x1:
667 svcin();
668 break;
669 case 0x2:
670 svcout();
671 break;
672 }
673 sys->cpu->pr += 2;
674 }
675
676 void exec()
677 {
678 clock_t clock_begin = 0;
679 clock_t clock_end = 0;
680 void (*cmdptr)() = NULL;
681 char *s = NULL;
682 const char *monmsg = "COMET II machine code monitor. Type ? for help.\n";
683
684 create_cmdtable(HASH_CODE);
685
686 if(execmode.trace == true) {
687 fprintf(stdout, "\nExecuting machine codes\n");
688 }
689
690 for (sys->cpu->pr = execptr->start; ; ) {
691 clock_begin = clock();
692 if(execmode.dump || execmode.trace) {
693 if(execmode.trace) {
694 fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
695 dspregister();
696 }
697 if(execmode.dump) {
698 fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
699 dumpmemory(execmode.dump_start, execmode.dump_end);
700 }
701 fprintf(stdout, "\n");
702 }
703
704 if(
705 (execmode.monitor == true && sys->cpu->pr == execptr->start) ||
706 execmode.step == true || getbps(sys->cpu->pr) == true)
707 {
708 if(sys->cpu->pr == execptr->start) {
709 fprintf(stdout, "%s", monmsg);
710 }
711 monitor();
712 }
713
714 if(sys->cpu->pr >= sys->memsize) {
715 setcerr(201, s = pr2str(sys->cpu->pr));
716 goto execfin;
717 }
718
719 if(sys->cpu->sp <= execptr->end) {
720 setcerr(202, s = pr2str(sys->cpu->pr));
721 goto execfin;
722 }
723
724
725 if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
726 setcerr(204, s = pr2str(sys->cpu->pr));
727 goto execfin;
728 }
729
730 (*cmdptr)();
731
732 if(cerr->num > 0) {
733 goto execfin;
734 }
735
736 if(execptr->stop == true) {
737 if(execmode.monitor == true) {
738 fprintf(stdout, "Return to top.\n");
739 monitor();
740 } else {
741 break;
742 }
743 }
744
745 do {
746 clock_end = clock();
747 } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
748 }
749 execfin:
750 FREE(s);
751 freebps();
752 free_cmdtable(HASH_CODE);
753 if(cerr->num > 0) {
754 fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);
755 }
756 }