4 * (C) Copyright 1989-1995
16 //#if !defined(_MSC_VER)
25 * The module asout.c contains all the functions used to
26 * generate the .REL assembler output file.
29 * The assemblers' output object file is an ascii file containing
30 * the information needed by the linker to bind multiple object
31 * modules into a complete loadable memory image.
33 * The object module contains the following designators:
40 * H Most significant byte first
41 * L Least significant byte first
48 * R Relocation information
49 * P Paging information
54 * The first line of an object module contains the [XDQ][HL]
55 * format specifier (i.e. XH indicates a hexidecimal file with
56 * most significant byte first) for the following designators.
61 * H aa areas gg global symbols
63 * The header line specifies the number of areas(aa) and the
64 * number of global symbols(gg) defined or referenced in this ob-
65 * ject module segment.
72 * The module line specifies the module name from which this
73 * header segment was assembled. The module line will not appear
74 * if the .module directive was not used in the source program.
85 * The symbol line defines (Def) or references (Ref) the symbol
86 * 'string' with the value nnnn. The defined value is relative to
87 * the current area base address. References to constants and ex-
88 * ternal global symbols will always appear before the first area
89 * definition. References to external symbols will have a value of
95 * A label size ss flags ff
97 * The area line defines the area label, the size (ss) of the
98 * area in bytes, and the area flags (ff). The area flags specify
99 * the ABS, REL, CON, OVR, and PAG parameters:
101 * OVR/CON (0x04/0x00 i.e. bit position 2)
103 * ABS/REL (0x08/0x00 i.e. bit position 3)
105 * PAG (0x10 i.e. bit position 4)
110 * T xx xx nn nn nn nn nn ...
112 * The T line contains the assembled code output by the assem-
113 * bler with xx xx being the offset address from the current area
114 * base address and nn being the assembled instructions and data in
120 * R 0 0 nn nn n1 n2 xx xx ...
122 * The R line provides the relocation information to the linker.
123 * The nn nn value is the current area index, i.e. which area the
124 * current values were assembled. Relocation information is en-
125 * coded in groups of 4 bytes:
127 * 1. n1 is the relocation mode and object format
128 * 1. bit 0 word(0x00)/byte(0x01)
129 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
130 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
131 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
133 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
134 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
135 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
136 * 8. bit 7 normal(0x00)/MSB of value
138 * 2. n2 is a byte index into the corresponding (i.e. pre-
139 * ceeding) T line data (i.e. a pointer to the data to be
140 * updated by the relocation). The T line data may be
141 * 1-byte or 2-byte byte data format or 2-byte word
144 * 3. xx xx is the area/symbol index for the area/symbol be-
145 * ing referenced. the corresponding area/symbol is found
146 * in the header area/symbol lists.
149 * The groups of 4 bytes are repeated for each item requiring relo-
150 * cation in the preceeding T line.
155 * P 0 0 nn nn n1 n2 xx xx
157 * The P line provides the paging information to the linker as
158 * specified by a .setdp directive. The format of the relocation
159 * information is identical to that of the R line. The correspond-
160 * ing T line has the following information:
161 * T xx xx aa aa bb bb
163 * Where aa aa is the area reference number which specifies the
164 * selected page area and bb bb is the base address of the page.
165 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
166 * specified in the P line. The linker will verify that the base
167 * address is on a 256 byte boundary and that the page length of an
168 * area defined with the PAG type is not larger than 256 bytes.
170 * The linker defaults any direct page references to the first
171 * area defined in the input REL file. All ASxxxx assemblers will
172 * specify the _CODE area first, making this the default page area.
175 * asout.c contains the following functions:
196 * The module asout.c contains the following local variables:
197 * int rel[] relocation data for code/data array
198 * int * relp pointer to rel array
199 * int txt[] assembled code/data array
200 * int * txtp pointer to txt array
209 char *txtp = { &txt[0] };
210 char *relp = { &rel[0] };
212 /*)Function VOID outab(b)
214 * int b assembler data word
216 * The function outab() processes a single word of
217 * assembled data in absolute format.
220 * int * txtp pointer to data word
223 * int oflag -o, generate relocatable output flag
224 * int pass assembler pass number
227 * VOID outchk() asout.c
228 * VOID out_lb() asout.c
231 * The current assembly address is incremented by 1.
247 /*)Function VOID outaw(w)
249 * int w assembler data word
251 * The function outaw() processes a single word of
252 * assembled data in absolute format.
255 * int * txtp pointer to data word
258 * int oflag -o, generate relocatable output flag
259 * int pass assembler pass number
262 * VOID outchk() asout.c
263 * VOID out_lw() asout.c
266 * The current assembly address is incremented by 2.
282 /*)Function VOID outrb(esp, r)
284 * expr * esp pointer to expr structure
285 * int r relocation mode
287 * The function outrb() processes a byte of generated code
288 * in either absolute or relocatable format dependent upon
289 * the data contained in the expr structure esp. If the
290 * .REL output is enabled then the appropriate information
291 * is loaded into the txt and rel buffers.
294 * int n symbol/area reference number
295 * int * relp pointer to rel array
296 * int * txtp pointer to txt array
299 * sym dot defined as sym[0]
300 * int oflag -o, generate relocatable output flag
301 * int pass assembler pass number
304 * VOID aerr() assubr.c
305 * VOID outchk() asout.c
306 * VOID out_lb() asout.c
307 * VOID out_rb() asout.c
308 * VOID out_tb() asout.c
311 * The current assembly address is incremented by 1.
316 register struct expr *esp;
322 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
323 out_lb(lobyte(esp->e_addr),0);
326 *txtp++ = lobyte(esp->e_addr);
329 r |= R_BYTE | R_BYT2 | esp->e_rlcf;
331 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
333 out_lb(lobyte(esp->e_addr),r|R_RELOC);
339 n = esp->e_base.e_sp->s_ref;
342 n = esp->e_base.e_ap->a_ref;
345 *relp++ = txtp - txt - 2;
353 /*)Function VOID outrw(esp, r)
355 * expr * esp pointer to expr structure
356 * int r relocation mode
358 * The function outrw() processes a word of generated code
359 * in either absolute or relocatable format dependent upon
360 * the data contained in the expr structure esp. If the
361 * .REL output is enabled then the appropriate information
362 * is loaded into the txt and rel buffers.
365 * int n symbol/area reference number
366 * int * relp pointer to rel array
367 * int * txtp pointer to txt array
370 * sym dot defined as sym[0]
371 * int oflag -o, generate relocatable output flag
372 * int pass assembler pass number
375 * VOID aerr() assubr.c
376 * VOID outchk() asout.c
377 * VOID out_lw() asout.c
378 * VOID out_rw() asout.c
379 * VOID out_tw() asout.c
382 * The current assembly address is incremented by 2.
387 register struct expr *esp;
393 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
394 out_lw(esp->e_addr,0);
400 r |= R_WORD | esp->e_rlcf;
404 out_lw(hibyte(esp->e_addr),r|R_RELOC);
406 out_lw(lobyte(esp->e_addr),r|R_RELOC);
409 out_lw(esp->e_addr,r|R_RELOC);
415 n = esp->e_base.e_sp->s_ref;
418 n = esp->e_base.e_ap->a_ref;
421 *relp++ = txtp - txt - 2;
429 /*)Function VOID outdp(carea, esp)
431 * area * carea pointer to current area strcuture
432 * expr * esp pointer to expr structure
434 * The function outdp() flushes the output buffer and
435 * outputs paging information to the .REL file.
438 * int n symbol/area reference number
439 * int r relocation mode
440 * int * relp pointer to rel array
441 * int * txtp pointer to txt array
444 * int oflag -o, generate relocatable output flag
445 * int pass assembler pass number
448 * VOID outbuf() asout.c
449 * VOID outchk() asout.c
450 * VOID out_rw() asout.c
451 * VOID out_tw() asout.c
454 * Output buffer flushed to .REL fiel.
455 * Paging information dumped to .REL file.
460 register struct area *carea;
461 register struct expr *esp;
465 if (oflag && pass==2) {
467 out_tw(carea->a_ref);
469 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
472 n = esp->e_base.e_sp->s_ref;
475 n = esp->e_base.e_ap->a_ref;
478 *relp++ = txtp - txt - 2;
485 /*)Function VOID outall()
487 * The function outall() will output any bufferred assembled
488 * data and relocation information (during pass 2 if the .REL
489 * output has been enabled).
495 * int oflag -o, generate relocatable output flag
496 * int pass assembler pass number
499 * VOID outbuf() asout.c
502 * assembled data and relocation buffers will be cleared.
508 if (oflag && pass==2)
512 /*)Function VOID outdot()
514 * The function outdot() outputs information about the
515 * current program counter value (during pass 2 if the .REL
516 * output has been enabled).
522 * int oflag -o, generate relocatable output flag
523 * int pass assembler pass number
526 * int fprintf() c_library
530 * assembled data and relocation buffers will be cleared.
536 if (oflag && pass==2) {
538 out(txt,(int) (txtp-txt));
541 out(rel,(int) (relp-rel));
548 /*)Function outchk(nt, nr)
550 * int nr number of additional relocation words
551 * int nt number of additional data words
553 * The function outchk() checks the data and relocation buffers
554 * for space to insert the nt data words and nr relocation words.
555 * If space is not available then output the current data and
556 * initialize the data buffers to receive the new data.
559 * area * ap pointer to an area structure
560 * int * relp pointer to rel array
561 * int * txtp pointer to txt array
564 * sym dot defined as sym[0]
567 * VOID outbuf() asout.c
570 * Data and relocation buffers may be emptied and initialized.
576 register struct area *ap;
578 if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
583 if ((ap = dot.s_area) != NULL) {
584 *relp++ = R_WORD|R_AREA;
591 /*)Function VOID outbuf()
593 * The function outbuf() will output any bufferred data
594 * and relocation information to the .REL file. The output
595 * buffer pointers and counters are initialized.
598 * int rel[] relocation data for code/data array
599 * int * relp pointer to rel array
600 * int txt[] assembled code/data array
601 * int * txtp pointer to txt array
604 * FILE * ofp relocation output file handle
610 * All bufferred data written to .REL file and
611 * buffer pointers and counters initialized.
618 if (txtp > &txt[2]) {
620 out(txt,(int) (txtp-txt));
623 out(rel,(int) (relp-rel));
630 /*)Function VOID outgsd()
632 * The function outgsd() performs the following:
633 * (1) outputs the .REL file radix
634 * (2) outputs the header specifying the number
635 * of areas and global symbols
636 * (3) outputs the module name
637 * (4) set the reference number and output a symbol line
638 * for all external global variables and absolutes
639 * (5) output an area name, set reference number and output
640 * a symbol line for all global relocatables in the area.
641 * Repeat this proceedure for all areas.
644 * area * ap pointer to an area structure
645 * sym * sp pointer to a sym structure
648 * int c string character value
649 * int narea number of code areas
650 * char * ptr string pointer
651 * int nglob number of global symbols
652 * int rn symbol reference number
655 * area * areap pointer to an area structure
656 * char module[] module name string
657 * sym * symhash[] array of pointers to NHASH
658 * linked symbol lists
659 * int xflag -x, listing radix flag
662 * int fprintf() c_library
663 * VOID outarea() asout.c
664 * VOID outsym() asout.c
665 * int putc() c_library
668 * All symbols are given reference numbers, all symbol
669 * and area information is output to the .REL file.
675 register struct area *ap;
676 register struct sym *sp;
679 int c, narea, nglob, rn;
684 narea = areap->a_ref + 1;
687 * Number of global references/absolutes
690 for (i = 0; i < NHASH; ++i) {
693 if (sp->s_flag&S_GBL)
700 * Output Radix and number of areas and symbols
703 fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
704 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
707 fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
708 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
711 fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
712 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
721 while (ptr < &module[NCPS]) {
722 if ((c = *ptr++) != 0)
729 * Global references and absolutes.
732 for (i=0; i<NHASH; ++i) {
735 if (sp->s_area==NULL && sp->s_flag&S_GBL) {
744 * Global relocatables.
746 for (i=0; i<narea; ++i) {
748 while (ap->a_ref != i)
751 for (j=0; j<NHASH; ++j) {
754 if (sp->s_area==ap && sp->s_flag&S_GBL) {
764 /*)Function VOID outarea(ap)
766 * area * ap pointer to an area structure
768 * The function outarea() outputs the A line to the .REL
769 * file. The A line contains the area's name, size, and
773 * char * ptr pointer to area id string
774 * int c character value
777 * FILE * ofp relocation output file handle
778 * int xflag -x, listing radix flag
781 * int fprintf() c_library
782 * int putc() c_library
785 * The A line is sent to the .REL file.
790 register struct area *ap;
797 while (ptr < &ap->a_id[NCPS]) {
798 if ((c = *ptr++) != 0)
802 fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
805 fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
808 fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
812 /*)Function VOID outsym(sp)
814 * sym * sp pointer to a sym structure
816 * The function outsym() outputs the S line to the .REL
817 * file. The S line contains the symbols name and whether the
818 * the symbol is defined or referenced.
821 * char * ptr pointer to symbol id string
822 * int c character value
825 * FILE * ofp relocation output file handle
826 * int xflag -x, listing radix flag
829 * int fprintf() c_library
830 * int putc() c_library
833 * The S line is sent to the .REL file.
838 register struct sym *sp;
845 while (ptr < &sp->s_id[NCPS]) {
846 if ((c = *ptr++) != 0)
849 fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
851 fprintf(ofp, "%04X\n", sp->s_addr);
854 fprintf(ofp, "%06o\n", sp->s_addr);
857 fprintf(ofp, "%05u\n", sp->s_addr);
861 /*)Function VOID out(p, n)
863 * int n number of words to output
864 * int * p pointer to data words
866 * The function out() outputs the data words to the .REL file
867 * int the specified radix.
873 * FILE * ofp relocation output file handle
874 * int xflag -x, listing radix flag
877 * int fprintf() c_library
880 * Data is sent to the .REL file.
890 fprintf(ofp, " %02X", (*p++)&0377);
893 fprintf(ofp, " %03o", (*p++)&0377);
896 fprintf(ofp, " %03u", (*p++)&0377);
901 /*)Function VOID out_lb(b, t)
903 * int b assembled data
904 * int t relocation type
906 * The function out_lb() copies the assembled data and
907 * its relocation type to the list data buffers.
913 * int * cp pointer to assembler output array cb[]
914 * int * cpt pointer to assembler relocation type
921 * Pointers to data and relocation buffers incremented by 1.
928 if (cp < &cb[NCODE]) {
934 /*)Function VOID out_lw(n, t)
936 * int n assembled data
937 * int t relocation type
939 * The function out_lw() copies the assembled data and
940 * its relocation type to the list data buffers.
946 * int * cp pointer to assembler output array cb[]
947 * int * cpt pointer to assembler relocation type
954 * Pointers to data and relocation buffers incremented by 2.
962 out_lb(hibyte(n),t ? t|R_HIGH : 0);
966 out_lb(hibyte(n),t ? t|R_HIGH : 0);
970 /*)Function VOID out_rw(n)
974 * The function out_rw() outputs the relocation (R)
975 * data word as two bytes ordered according to hilo.
978 * int * relp pointer to rel array
984 * int lobyte() asout.c
985 * int hibyte() asout.c
988 * Pointer to relocation buffer incremented by 2.
1000 *relp++ = hibyte(n);
1004 /*)Function VOID out_tw(n)
1008 * The function out_tw() outputs the text (T)
1009 * data word as two bytes ordered according to hilo.
1012 * int * txtp pointer to txt array
1018 * int lobyte() asout.c
1019 * int hibyte() asout.c
1022 * Pointer to relocation buffer incremented by 2.
1030 *txtp++ = hibyte(n);
1031 *txtp++ = lobyte(n);
1033 *txtp++ = lobyte(n);
1034 *txtp++ = hibyte(n);
1038 /*)Function int lobyte(n)
1042 * The function lobyte() returns the lower byte of
1064 /*)Function int hibyte(n)
1068 * The function hibyte() returns the higher byte of
1087 return ((n>>8)&0377);