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