This source file includes following definitions.
- printline
- getadr
- grword
- getliteral
- writememory
- writestr
- writedc
- assemble_start
- assemble_end
- assemble_ds
- assemble_dc
- assemble_in
- assemble_out
- assemble_rpush
- assemble_rpop
- casl2cmd
- assemble_comet2cmd
- assembletok
- assembleline
- assemblefile
- assemble
- addcerrlist_assemble
- outassemble
1 #include "assemble.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <assert.h>
7 #include <errno.h>
8
9
10
11
12
13
14
15
16
17 void printline(FILE *stream, const char *filename, int lineno, char *line);
18
19
20
21
22
23
24
25
26
27
28
29
30 WORD getadr(const char *prog, const char *str, PASS pass);
31
32
33
34
35
36
37
38
39
40
41
42
43
44 WORD grword(const char *str, bool is_x);
45
46
47
48
49
50
51
52
53
54 WORD getliteral(const char *str, PASS pass);
55
56
57
58
59
60
61
62
63 void writememory(WORD word, WORD adr, PASS pass);
64
65
66
67
68
69
70
71
72 void writestr(const char *str, bool literal, PASS pass);
73
74
75
76
77
78
79
80 void writedc(const char *str, PASS pass);
81
82
83
84
85
86
87
88
89 void assemble_start(const CMDLINE *cmdl, PASS pass);
90
91
92
93
94
95
96
97
98 void assemble_ds(const CMDLINE *cmdl, PASS pass);
99
100
101
102
103
104
105
106
107 void assemble_end(const CMDLINE *cmdl, PASS pass);
108
109
110
111
112
113
114
115
116 void assemble_dc(const CMDLINE *cmdl, PASS pass);
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 void assemble_in(const CMDLINE *cmdl, PASS pass);
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 void assemble_out(const CMDLINE *cmdl, PASS pass);
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 void assemble_rpush(const CMDLINE *cmdl, PASS pass);
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 void assemble_rpop(const CMDLINE *cmdl, PASS pass);
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 bool casl2cmd(CMD *cmdtbl, const CMDLINE *cmdl, PASS pass);
218
219
220
221
222
223
224
225
226
227 bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass);
228
229
230
231
232
233
234
235
236
237 bool assembletok(const CMDLINE *cmdl, PASS pass);
238
239
240
241
242
243
244
245
246
247
248
249 bool assembleline(const char *line, PASS pass);
250
251
252
253
254 static CERR cerr_assemble[] = {
255 { 106, "operand mismatch in CASL II command" },
256 { 107, "no label in START" },
257 { 108, "not command of operand \"r\"" },
258 { 109, "not command of operand \"r1,r2\"" },
259 { 110, "not command of operand \"r,adr[,x]\"" },
260 { 111, "not command of operand \"adr[,x]\"" },
261 { 112, "not command of no operand" },
262 { 113, "operand too many in COMET II command" },
263 { 119, "out of COMET II memory" },
264 { 120, "GR0 in operand x" },
265 { 122, "cannot create hash table" },
266 { 124, "more than one character in literal" },
267 { 125, "not GR in operand x" },
268 };
269
270
271
272
273 static CMD ascmd[] = {
274 { "START", assemble_start },
275 { "END", assemble_end },
276 { "DS", assemble_ds },
277 { "DC", assemble_dc },
278 { "", NULL }
279 };
280
281
282
283
284 static CMD macrocmd[] = {
285 { "OUT", assemble_out },
286 { "IN", assemble_in },
287 { "RPUSH", assemble_rpush },
288 { "RPOP", assemble_rpop },
289 { "", NULL }
290 };
291
292 ASPTR *asptr = NULL;
293
294 ASMODE asmode = {false, false, false, false, false};
295
296 void printline(FILE *stream, const char *filename, int lineno, char *line)
297 {
298 fprintf(stream, "%s:%5d:%s", filename, lineno, line);
299 }
300
301 WORD getadr(const char *prog, const char *str, PASS pass)
302 {
303 WORD adr = 0;
304
305 if(str[0] == '=') {
306 adr = getliteral(str, pass);
307 } else if(isdigit(str[0]) || str[0] == '-' || str[0] == '#') {
308 adr = nh2word(str);
309 } else {
310 if(pass == SECOND) {
311 if((adr = getlabel(prog, str)) == 0xFFFF) {
312 adr = getlabel("", str);
313 }
314 if(adr == 0xFFFF) {
315 setcerr(103, str); setcerr(103, str);
316 }
317 }
318 }
319 return adr;
320 }
321
322 WORD grword(const char *str, bool is_x)
323 {
324 WORD r = 0;
325
326
327 if(strlen(str) != 3 ||
328 strncmp(str, "GR", 2) != 0 ||
329 str[2] < '0' || str[2] > '0' + (GRSIZE - 1))
330 {
331 return 0xFFFF;
332 }
333 r = (WORD)(str[2] - '0');
334
335 if(is_x == true && r == 0x0) {
336 setcerr(120, "");
337 return 0;
338 }
339 return r;
340 }
341
342 WORD getliteral(const char *str, PASS pass)
343 {
344 assert(str[0] == '=');
345 WORD adr = asptr->lptr;
346
347 str++;
348 if(str[0] == '\'') {
349 writestr(str, true, pass);
350 } else {
351 writememory(nh2word(str), (asptr->lptr)++, pass);
352 }
353 return adr;
354 }
355
356 void writememory(WORD word, WORD adr, PASS pass)
357 {
358 char *n = NULL;
359
360
361 if(adr >= sys->memsize) {
362 setcerr(119, (n = word2n(adr)));
363 FREE(n);
364 return;
365 }
366 (sys->memory)[adr] = word;
367 if(pass == SECOND && asmode.asdetail == true) {
368 fprintf(stdout, "\t#%04X\t#%04X\n", adr, word);
369 }
370 }
371
372 void writestr(const char *str, bool literal, PASS pass)
373 {
374 assert(str[0] == '\'');
375 bool lw = false;
376
377
378 for(int i = 1; str[i] != '\'' || str[++i] == '\''; i++) {
379
380 if(!str[i]) {
381 setcerr(123, str);
382 break;
383 }
384 if(literal == true && lw == true) {
385 setcerr(124, str);
386 break;
387 }
388
389 if(literal == true) {
390 writememory(str[i], (asptr->lptr)++, pass);
391 lw = true;
392 } else {
393 writememory(str[i], (asptr->ptr)++, pass);
394 }
395 }
396 }
397
398 void writedc(const char *str, PASS pass)
399 {
400 WORD adr = 0;
401
402 if(*str == '\'') {
403 writestr(str, false, pass);
404 } else {
405 if(str[0] == '#' || isdigit(str[0]) || str[0] == '-') {
406 adr = nh2word(str);
407 } else {
408 if(pass == SECOND && (adr = getlabel(asptr->prog, str)) == 0xFFFF) {
409 adr = getlabel("", str);
410 }
411 if(pass == SECOND && adr == 0xFFFF) {
412 setcerr(103, str);
413 }
414 }
415 writememory(adr, (asptr->ptr)++, pass);
416 }
417 }
418
419 void assemble_start(const CMDLINE *cmdl, PASS pass)
420 {
421 if(cmdl->opd->opdc > 1) {
422 setcerr(106, "");
423 return;
424 }
425 if(!cmdl->label[0]) {
426 setcerr(107, "");
427 return;
428 }
429
430 strcpy(asptr->prog, cmdl->label);
431
432 if(cmdl->opd->opdv[0] != NULL) {
433 asptr->ptr = execptr->start = getadr(asptr->prog, cmdl->opd->opdv[0], pass);
434 }
435 }
436
437 void assemble_end(const CMDLINE *cmdl, PASS pass)
438 {
439 if(cmdl->opd->opdc > 0) {
440 setcerr(106, "");
441 return;
442 }
443
444 if(pass == FIRST) {
445 asptr->lptr = asptr->ptr;
446 }
447
448 else if(pass == SECOND) {
449 execptr->end = asptr->lptr;
450 }
451 strcpy(asptr->prog, "");
452 }
453
454 void assemble_ds(const CMDLINE *cmdl, PASS pass)
455 {
456 if(cmdl->opd->opdc != 1) {
457 setcerr(106, "");
458 return;
459 }
460 for(int i = 0; i < atoi(cmdl->opd->opdv[0]); i++) {
461 writememory(0x0, (asptr->ptr)++, pass);
462 if(cerr->num > 0) {
463 break;
464 }
465 }
466 }
467
468 void assemble_dc(const CMDLINE *cmdl, PASS pass)
469 {
470 if(cmdl->opd->opdc == 0 || cmdl->opd->opdc >= OPDSIZE) {
471 setcerr(106, "");
472 return;
473 }
474 for(int i = 0; i < cmdl->opd->opdc; i++) {
475 writedc(cmdl->opd->opdv[i], pass);
476 if(cerr->num > 0) {
477 break;
478 }
479 }
480 }
481
482 void assemble_in(const CMDLINE *cmdl, PASS pass)
483 {
484 char *line = malloc_chk(LINESIZE + 1, "assemble_in.line");
485
486 if(cmdl->opd->opdc == 0 || cmdl->opd->opdc > 2) {
487 setcerr(106, "");
488 return;
489 }
490 assembleline(" PUSH 0,GR1", pass);
491 assembleline(" PUSH 0,GR2", pass);
492 sprintf(line, " LAD GR1,%s", cmdl->opd->opdv[0]);
493 assembleline(line, pass);
494 sprintf(line, " LAD GR2,%s", cmdl->opd->opdv[1]);
495 assembleline(line, pass);
496 assembleline(" SVC 1", pass);
497 assembleline(" POP GR2", pass);
498 assembleline(" POP GR1", pass);
499 FREE(line);
500 }
501
502 void assemble_out(const CMDLINE *cmdl, PASS pass)
503 {
504 char *line = malloc_chk(LINESIZE + 1, "assemble_out.line");
505
506 if(cmdl->opd->opdc == 0 || cmdl->opd->opdc > 2) {
507 setcerr(106, "");
508 return;
509 }
510 assembleline(" PUSH 0,GR1", pass);
511 assembleline(" PUSH 0,GR2", pass);
512 sprintf(line, " LAD GR1,%s", cmdl->opd->opdv[0]);
513 assembleline(line, pass);
514 sprintf(line, " LAD GR2,%s", cmdl->opd->opdv[1]);
515 assembleline(line, pass);
516 assembleline(" SVC 2", pass);
517 assembleline(" LAD GR1,=#A", pass);
518 assembleline(" LAD GR2,=1", pass);
519 assembleline(" SVC 2", pass);
520 assembleline(" POP GR2", pass);
521 assembleline(" POP GR1", pass);
522 FREE(line);
523 }
524
525 void assemble_rpush(const CMDLINE *cmdl, PASS pass)
526 {
527 char *line = malloc_chk(LINESIZE + 1, "assemble_rpush.line");
528
529 if(cmdl->opd->opdc > 0) {
530 setcerr(106, "");
531 return;
532 }
533 for(int i = 1; i <= GRSIZE-1; i++) {
534 sprintf(line, " PUSH 0,GR%d", i);
535 assembleline(line, pass);
536 }
537 FREE(line);
538 }
539
540 void assemble_rpop(const CMDLINE *cmdl, PASS pass)
541 {
542 char *line = malloc_chk(LINESIZE + 1, "assemble_rpop.line");
543
544 if(cmdl->opd->opdc > 0) {
545 setcerr(106, "");
546 return;
547 }
548 for(int i = GRSIZE-1; i >= 1; i--) {
549 sprintf(line, " POP GR%d", i);
550 assembleline(line, pass);
551 }
552 FREE(line);
553 }
554
555 bool casl2cmd(CMD *cmdtbl, const CMDLINE *cmdl, PASS pass)
556 {
557 void (*cmdptr)(const CMDLINE *, PASS) = NULL;
558
559 for(int i = 0; cmdtbl[i].name[0]; i++) {
560 if(strcmp(cmdl->cmd, cmdtbl[i].name) == 0) {
561 cmdptr = cmdtbl[i].ptr;
562 (*cmdptr)(cmdl, pass);
563 return true;
564 }
565 }
566 return false;
567 }
568
569 bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass)
570 {
571 WORD cmd = 0;
572 WORD r_r1 = 0;
573 WORD x_r2 = 0;
574 WORD adr = 0;
575
576
577 if(cmdl->opd->opdc == 0) {
578 if((cmd = getcmdcode(cmdl->cmd, NONE)) == 0xFFFF) {
579 setcerr(112, cmdl->cmd);
580 return false;
581 }
582 writememory(cmd, (asptr->ptr)++, pass);
583 }
584
585 else if((r_r1 = grword(cmdl->opd->opdv[0], false)) != 0xFFFF) {
586
587 if(cmdl->opd->opdc == 1) {
588 if((cmd = getcmdcode(cmdl->cmd, R_)) == 0xFFFF) {
589 setcerr(108, cmdl->cmd);
590 return false;
591 }
592 cmd |= (r_r1 << 4);
593 writememory(cmd, (asptr->ptr)++, pass);
594 }
595
596 else if(cmdl->opd->opdc == 2 && (x_r2 = grword(cmdl->opd->opdv[1], false)) != 0xFFFF) {
597 if((cmd = getcmdcode(cmdl->cmd, R1_R2)) == 0xFFFF) {
598 setcerr(109, cmdl->cmd);
599 return false;
600 }
601 cmd |= ((r_r1 << 4) | x_r2);
602
603 writememory(cmd, (asptr->ptr)++, pass);
604 }
605
606 else if(cmdl->opd->opdc == 2 || cmdl->opd->opdc == 3) {
607 if((cmd = getcmdcode(cmdl->cmd, R_ADR_X)) == 0xFFFF) {
608 setcerr(110, cmdl->cmd);
609 return false;
610 }
611 cmd |= (r_r1 << 4);
612
613 if(cmdl->opd->opdc == 3) {
614 if((x_r2 = grword(cmdl->opd->opdv[2], true)) == 0xFFFF) {
615 setcerr(125, cmdl->cmd);
616 return false;
617 }
618 cmd |= x_r2;
619 }
620 adr = getadr(asptr->prog, cmdl->opd->opdv[1], pass);
621
622 writememory(cmd, (asptr->ptr)++, pass);
623 writememory(adr, (asptr->ptr)++, pass);
624 } else {
625 setcerr(113, cmdl->cmd);
626 return false;
627 }
628 }
629
630 else if(cmdl->opd->opdc == 1 || cmdl->opd->opdc == 2) {
631 if((cmd = getcmdcode(cmdl->cmd, ADR_X)) == 0xFFFF) {
632 setcerr(111, cmdl->cmd);
633 return false;
634 }
635
636 if(cmdl->opd->opdc == 2) {
637 x_r2 = grword(cmdl->opd->opdv[1], true);
638 if(cerr->num > 0) {
639 return false;
640 }
641 cmd |= x_r2;
642 }
643
644
645
646 if(pass == SECOND && cmd == 0x8000) {
647 adr = getlabel("", cmdl->opd->opdv[0]);
648 }
649 if(cmd != 0x8000 || (pass == SECOND && adr == 0xFFFF)) {
650 adr = getadr(asptr->prog, cmdl->opd->opdv[0], pass);
651 }
652
653 writememory(cmd, (asptr->ptr)++, pass);
654 writememory(adr, (asptr->ptr)++, pass);
655 }
656 return (cerr->num == 0) ? true : false;
657 }
658
659 bool assembletok(const CMDLINE *cmdl, PASS pass)
660 {
661
662 if(!cmdl->cmd[0]) {
663 return true;
664 }
665
666 if(casl2cmd(ascmd, cmdl, pass) == false && casl2cmd(macrocmd, cmdl, pass) == false) {
667
668 if(assemble_comet2cmd(cmdl, pass) == false) {
669 if(cerr->num == 0) {
670 setcerr(113, cmdl->cmd);
671 }
672 }
673 }
674 return (cerr->num == 0) ? true : false;
675 }
676
677 bool assembleline(const char *line, PASS pass)
678 {
679 CMDLINE *cmdl = NULL;
680 bool stat = true;
681
682 cmdl = linetok(line);
683 stat = (cerr->num == 0) ? true : false;
684 if(cmdl != NULL) {
685 if(stat == true) {
686 if(pass == FIRST && cmdl->label[0]) {
687 stat = addlabel(asptr->prog, cmdl->label, asptr->ptr);
688 }
689 }
690 if(stat == true) {
691 stat = assembletok(cmdl, pass);
692 }
693 FREE(cmdl->label);
694 if(cmdl->opd != NULL) {
695 for(int i = 0; i < cmdl->opd->opdc; i++) {
696 FREE(cmdl->opd->opdv[i]);
697 }
698 }
699 FREE(cmdl->opd);
700 FREE(cmdl->cmd);
701 }
702 FREE(cmdl);
703 return stat;
704 }
705
706
707
708
709
710
711 bool assemblefile(const char *file, PASS pass)
712 {
713 int lineno = 1;
714 char *line = NULL;
715 FILE *fp = NULL;
716
717 if((fp = fopen(file, "r")) == NULL) {
718 cerr->num = errno;
719 perror(file);
720 return false;
721 }
722 for(line = malloc_chk(LINESIZE + 1, "assemble.line"); fgets(line, LINESIZE, fp); lineno++) {
723 if((pass == FIRST && asmode.src == true) || (pass == SECOND && asmode.asdetail == true)) {
724 printline(stdout, file, lineno, line);
725 }
726 if(assembleline(line, pass) == false) {
727 break;
728 }
729 }
730 if(cerr->num > 0) {
731 fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg);
732 printline(stderr, file, lineno, line);
733 }
734 FREE(line);
735 fclose(fp);
736 return (cerr->num == 0) ? true : false;
737 }
738
739 bool assemble(int filec, char *filev[], WORD adr)
740 {
741 int i;
742 PASS pass;
743 WORD bp[filec];
744 bool stat = false;
745
746 asptr = malloc_chk(sizeof(ASPTR), "asptr");
747 asptr->prog = malloc_chk(LABELSIZE + 1, "asptr.prog");
748 asptr->ptr = adr;
749
750 for(pass = FIRST; pass <= SECOND; pass++) {
751 for(i = 0; i < filec; i++) {
752
753 if(pass == FIRST) {
754 bp[i] = asptr->ptr;
755 } else if(pass == SECOND) {
756 asptr->ptr = bp[i];
757 }
758 if(execmode.trace == true || execmode.dump == true ||
759 asmode.src == true || asmode.label == true || asmode.asdetail == true)
760 {
761 fprintf(stdout, "\nAssemble %s (%d)\n", filev[i], pass);
762 }
763
764 stat = assemblefile(filev[i], pass);
765 if(stat == false) {
766 goto asfin;
767 }
768 }
769 if(pass == FIRST && asmode.label == true) {
770 fprintf(stdout, "\nLabel::::\n");
771 printlabel();
772 if(asmode.onlylabel == true) {
773 break;
774 }
775 }
776 }
777 asfin:
778 freelabel();
779 FREE(asptr->prog);
780 FREE(asptr);
781 return stat;
782 }
783
784
785 void addcerrlist_assemble()
786 {
787 addcerrlist_tok();
788 addcerrlist_word();
789 addcerrlist_label();
790 addcerrlist(ARRAYSIZE(cerr_assemble), cerr_assemble);
791 }
792
793 void outassemble(const char *file)
794 {
795 FILE *fp = NULL;
796
797 if((fp = fopen(file, "w")) == NULL) {
798 perror(file);
799 exit(1);
800 }
801 fwrite(sys->memory, sizeof(WORD), execptr->end, fp);
802 fclose(fp);
803 }