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