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