4 * (C) Copyright 1989-1995
12 * - applied changes from 28-Oct-97 JLH:
13 * - outsym: show s_id as string rather than array [NCPS]
24 * The module asout.c contains all the functions used to
25 * generate the .REL assembler output file.
28 * The assemblers' output object file is an ascii file containing
29 * the information needed by the linker to bind multiple object
30 * modules into a complete loadable memory image.
32 * The object module contains the following designators:
39 * H Most significant byte first
40 * L Least significant byte first
47 * R Relocation information
48 * P Paging information
53 * The first line of an object module contains the [XDQ][HL]
54 * format specifier (i.e. XH indicates a hexidecimal file with
55 * most significant byte first) for the following designators.
60 * H aa areas gg global symbols
62 * The header line specifies the number of areas(aa) and the
63 * number of global symbols(gg) defined or referenced in this ob-
64 * ject module segment.
71 * The module line specifies the module name from which this
72 * header segment was assembled. The module line will not appear
73 * if the .module directive was not used in the source program.
84 * The symbol line defines (Def) or references (Ref) the symbol
85 * 'string' with the value nnnn. The defined value is relative to
86 * the current area base address. References to constants and ex-
87 * ternal global symbols will always appear before the first area
88 * definition. References to external symbols will have a value of
94 * A label size ss flags ff
96 * The area line defines the area label, the size (ss) of the
97 * area in bytes, and the area flags (ff). The area flags specify
98 * the ABS, REL, CON, OVR, and PAG parameters:
100 * OVR/CON (0x04/0x00 i.e. bit position 2)
102 * ABS/REL (0x08/0x00 i.e. bit position 3)
104 * PAG (0x10 i.e. bit position 4)
109 * T xx xx nn nn nn nn nn ...
111 * The T line contains the assembled code output by the assem-
112 * bler with xx xx being the offset address from the current area
113 * base address and nn being the assembled instructions and data in
119 * R 0 0 nn nn n1 n2 xx xx ...
121 * The R line provides the relocation information to the linker.
122 * The nn nn value is the current area index, i.e. which area the
123 * current values were assembled. Relocation information is en-
124 * coded in groups of 4 bytes:
126 * 1. n1 is the relocation mode and object format
127 * 1. bit 0 word(0x00)/byte(0x01)
128 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
129 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
130 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
132 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
133 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
134 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
135 * 8. bit 7 normal(0x00)/MSB of value
137 * 2. n2 is a byte index into the corresponding (i.e. pre-
138 * ceeding) T line data (i.e. a pointer to the data to be
139 * updated by the relocation). The T line data may be
140 * 1-byte or 2-byte byte data format or 2-byte word
143 * 3. xx xx is the area/symbol index for the area/symbol be-
144 * ing referenced. the corresponding area/symbol is found
145 * in the header area/symbol lists.
148 * The groups of 4 bytes are repeated for each item requiring relo-
149 * cation in the preceeding T line.
154 * P 0 0 nn nn n1 n2 xx xx
156 * The P line provides the paging information to the linker as
157 * specified by a .setdp directive. The format of the relocation
158 * information is identical to that of the R line. The correspond-
159 * ing T line has the following information:
160 * T xx xx aa aa bb bb
162 * Where aa aa is the area reference number which specifies the
163 * selected page area and bb bb is the base address of the page.
164 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
165 * specified in the P line. The linker will verify that the base
166 * address is on a 256 byte boundary and that the page length of an
167 * area defined with the PAG type is not larger than 256 bytes.
169 * The linker defaults any direct page references to the first
170 * area defined in the input REL file. All ASxxxx assemblers will
171 * specify the _CODE area first, making this the default page area.
174 * asout.c contains the following functions:
195 * The module asout.c contains the following local variables:
196 * int rel[] relocation data for code/data array
197 * int * relp pointer to rel array
198 * int txt[] assembled code/data array
199 * int * txtp pointer to txt array
208 char *txtp = { &txt[0] };
209 char *relp = { &rel[0] };
211 /*)Function VOID outab(b)
213 * int b assembler data word
215 * The function outab() processes a single word of
216 * assembled data in absolute format.
219 * int * txtp pointer to data word
222 * int oflag -o, generate relocatable output flag
223 * int pass assembler pass number
226 * VOID outchk() asout.c
227 * VOID out_lb() asout.c
230 * The current assembly address is incremented by 1.
246 /*)Function VOID outaw(w)
248 * int w assembler data word
250 * The function outaw() processes a single word of
251 * assembled data in absolute format.
254 * int * txtp pointer to data word
257 * int oflag -o, generate relocatable output flag
258 * int pass assembler pass number
261 * VOID outchk() asout.c
262 * VOID out_lw() asout.c
265 * The current assembly address is incremented by 2.
281 /*)Function VOID outrb(esp, r)
283 * expr * esp pointer to expr structure
284 * int r relocation mode
286 * The function outrb() processes a byte of generated code
287 * in either absolute or relocatable format dependent upon
288 * the data contained in the expr structure esp. If the
289 * .REL output is enabled then the appropriate information
290 * is loaded into the txt and rel buffers.
293 * int n symbol/area reference number
294 * int * relp pointer to rel array
295 * int * txtp pointer to txt array
298 * sym dot defined as sym[0]
299 * int oflag -o, generate relocatable output flag
300 * int pass assembler pass number
303 * VOID aerr() assubr.c
304 * VOID outchk() asout.c
305 * VOID out_lb() asout.c
306 * VOID out_rb() asout.c
307 * VOID out_tb() asout.c
310 * The current assembly address is incremented by 1.
314 outrb(struct expr *esp, int r)
319 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
320 out_lb(lobyte(esp->e_addr),0);
323 *txtp++ = lobyte(esp->e_addr);
326 r |= R_BYTE | R_BYT2 | esp->e_rlcf;
328 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
330 out_lb(lobyte(esp->e_addr),r|R_RELOC);
336 n = esp->e_base.e_sp->s_ref;
339 n = esp->e_base.e_ap->a_ref;
342 *relp++ = txtp - txt - 2;
350 /*)Function VOID outrw(esp, r)
352 * expr * esp pointer to expr structure
353 * int r relocation mode
355 * The function outrw() processes a word of generated code
356 * in either absolute or relocatable format dependent upon
357 * the data contained in the expr structure esp. If the
358 * .REL output is enabled then the appropriate information
359 * is loaded into the txt and rel buffers.
362 * int n symbol/area reference number
363 * int * relp pointer to rel array
364 * int * txtp pointer to txt array
367 * sym dot defined as sym[0]
368 * int oflag -o, generate relocatable output flag
369 * int pass assembler pass number
372 * VOID aerr() assubr.c
373 * VOID outchk() asout.c
374 * VOID out_lw() asout.c
375 * VOID out_rw() asout.c
376 * VOID out_tw() asout.c
379 * The current assembly address is incremented by 2.
383 outrw(struct expr *esp, int r)
388 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
389 out_lw(esp->e_addr,0);
395 r |= R_WORD | esp->e_rlcf;
399 out_lw(hibyte(esp->e_addr),r|R_RELOC);
401 out_lw(lobyte(esp->e_addr),r|R_RELOC);
404 out_lw(esp->e_addr,r|R_RELOC);
410 n = esp->e_base.e_sp->s_ref;
413 n = esp->e_base.e_ap->a_ref;
416 *relp++ = txtp - txt - 2;
424 /*)Function VOID outdp(carea, esp)
426 * area * carea pointer to current area strcuture
427 * expr * esp pointer to expr structure
429 * The function outdp() flushes the output buffer and
430 * outputs paging information to the .REL file.
433 * int n symbol/area reference number
434 * int r relocation mode
435 * int * relp pointer to rel array
436 * int * txtp pointer to txt array
439 * int oflag -o, generate relocatable output flag
440 * int pass assembler pass number
443 * VOID outbuf() asout.c
444 * VOID outchk() asout.c
445 * VOID out_rw() asout.c
446 * VOID out_tw() asout.c
449 * Output buffer flushed to .REL fiel.
450 * Paging information dumped to .REL file.
454 outdp(struct area *carea, struct expr *esp)
458 if (oflag && pass==2) {
460 out_tw(carea->a_ref);
462 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
465 n = esp->e_base.e_sp->s_ref;
468 n = esp->e_base.e_ap->a_ref;
471 *relp++ = txtp - txt - 2;
478 /*)Function VOID outall()
480 * The function outall() will output any bufferred assembled
481 * data and relocation information (during pass 2 if the .REL
482 * output has been enabled).
488 * int oflag -o, generate relocatable output flag
489 * int pass assembler pass number
492 * VOID outbuf() asout.c
495 * assembled data and relocation buffers will be cleared.
501 if (oflag && pass==2)
505 /*)Function VOID outdot()
507 * The function outdot() outputs information about the
508 * current program counter value (during pass 2 if the .REL
509 * output has been enabled).
515 * int oflag -o, generate relocatable output flag
516 * int pass assembler pass number
519 * int fprintf() c_library
523 * assembled data and relocation buffers will be cleared.
529 if (oflag && pass==2) {
531 out(txt,(int) (txtp-txt));
534 out(rel,(int) (relp-rel));
541 /*)Function outchk(nt, nr)
543 * int nr number of additional relocation words
544 * int nt number of additional data words
546 * The function outchk() checks the data and relocation buffers
547 * for space to insert the nt data words and nr relocation words.
548 * If space is not available then output the current data and
549 * initialize the data buffers to receive the new data.
552 * area * ap pointer to an area structure
553 * int * relp pointer to rel array
554 * int * txtp pointer to txt array
557 * sym dot defined as sym[0]
560 * VOID outbuf() asout.c
563 * Data and relocation buffers may be emptied and initialized.
567 outchk(int nt, int nr)
569 register struct area *ap;
571 if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
576 if ((ap = dot.s_area) != NULL) {
577 *relp++ = R_WORD|R_AREA;
584 /*)Function VOID outbuf()
586 * The function outbuf() will output any bufferred data
587 * and relocation information to the .REL file. The output
588 * buffer pointers and counters are initialized.
591 * int rel[] relocation data for code/data array
592 * int * relp pointer to rel array
593 * int txt[] assembled code/data array
594 * int * txtp pointer to txt array
597 * FILE * ofp relocation output file handle
603 * All bufferred data written to .REL file and
604 * buffer pointers and counters initialized.
610 if (txtp > &txt[2]) {
612 out(txt,(int) (txtp-txt));
615 out(rel,(int) (relp-rel));
622 /*)Function VOID outgsd()
624 * The function outgsd() performs the following:
625 * (1) outputs the .REL file radix
626 * (2) outputs the header specifying the number
627 * of areas and global symbols
628 * (3) outputs the module name
629 * (4) set the reference number and output a symbol line
630 * for all external global variables and absolutes
631 * (5) output an area name, set reference number and output
632 * a symbol line for all global relocatables in the area.
633 * Repeat this proceedure for all areas.
636 * area * ap pointer to an area structure
637 * sym * sp pointer to a sym structure
640 * int c string character value
641 * int narea number of code areas
642 * char * ptr string pointer
643 * int nglob number of global symbols
644 * int rn symbol reference number
647 * area * areap pointer to an area structure
648 * char module[] module name string
649 * sym * symhash[] array of pointers to NHASH
650 * linked symbol lists
651 * int xflag -x, listing radix flag
654 * int fprintf() c_library
655 * VOID outarea() asout.c
656 * VOID outsym() asout.c
657 * int putc() c_library
660 * All symbols are given reference numbers, all symbol
661 * and area information is output to the .REL file.
667 register struct area *ap;
668 register struct sym *sp;
671 int c, narea, nglob, rn;
676 narea = areap->a_ref + 1;
679 * Number of global references/absolutes
682 for (i = 0; i < NHASH; ++i) {
685 if (sp->s_flag&S_GBL)
692 * Output Radix and number of areas and symbols
695 fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
696 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
699 fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
700 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
703 fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
704 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
713 while (ptr < &module[NCPS]) {
714 if ((c = *ptr++) != 0)
721 * Sdcc compile options
723 if (strlen(optsdcc)) fprintf(ofp, "O %s\n", optsdcc);
726 * Global references and absolutes.
729 for (i=0; i<NHASH; ++i) {
732 if (sp->s_area==NULL && sp->s_flag&S_GBL) {
741 * Global relocatables.
743 for (i=0; i<narea; ++i) {
745 while (ap->a_ref != i)
748 for (j=0; j<NHASH; ++j) {
751 if (sp->s_area==ap && sp->s_flag&S_GBL) {
761 /*)Function VOID outarea(ap)
763 * area * ap pointer to an area structure
765 * The function outarea() outputs the A line to the .REL
766 * file. The A line contains the area's name, size, and
770 * char * ptr pointer to area id string
771 * int c character value
774 * FILE * ofp relocation output file handle
775 * int xflag -x, listing radix flag
778 * int fprintf() c_library
779 * int putc() c_library
782 * The A line is sent to the .REL file.
786 outarea(struct area *ap)
788 fprintf(ofp, "A %s", ap->a_id);
790 fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
793 fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
796 fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
800 /*)Function VOID outsym(sp)
802 * sym * sp pointer to a sym structure
804 * The function outsym() outputs the S line to the .REL
805 * file. The S line contains the symbols name and whether the
806 * the symbol is defined or referenced.
809 * char * ptr pointer to symbol id string
810 * int c character value
813 * FILE * ofp relocation output file handle
814 * int xflag -x, listing radix flag
817 * int fprintf() c_library
818 * int putc() c_library
821 * The S line is sent to the .REL file.
825 outsym(struct sym *sp)
827 fprintf(ofp, "S %s", sp->s_id);
828 fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
830 fprintf(ofp, "%04X\n", sp->s_addr);
833 fprintf(ofp, "%06o\n", sp->s_addr);
836 fprintf(ofp, "%05u\n", sp->s_addr);
840 /*)Function VOID out(p, n)
842 * int n number of words to output
843 * int * p pointer to data words
845 * The function out() outputs the data words to the .REL file
846 * int the specified radix.
852 * FILE * ofp relocation output file handle
853 * int xflag -x, listing radix flag
856 * int fprintf() c_library
859 * Data is sent to the .REL file.
867 fprintf(ofp, " %02X", (*p++)&0377);
870 fprintf(ofp, " %03o", (*p++)&0377);
873 fprintf(ofp, " %03u", (*p++)&0377);
878 /*)Function VOID out_lb(b, t)
880 * int b assembled data
881 * int t relocation type
883 * The function out_lb() copies the assembled data and
884 * its relocation type to the list data buffers.
890 * int * cp pointer to assembler output array cb[]
891 * int * cpt pointer to assembler relocation type
898 * Pointers to data and relocation buffers incremented by 1.
904 if (cp < &cb[NCODE]) {
910 /*)Function VOID out_lw(n, t)
912 * int n assembled data
913 * int t relocation type
915 * The function out_lw() copies the assembled data and
916 * its relocation type to the list data buffers.
922 * int * cp pointer to assembler output array cb[]
923 * int * cpt pointer to assembler relocation type
930 * Pointers to data and relocation buffers incremented by 2.
937 out_lb(hibyte(n),t ? t|R_HIGH : 0);
941 out_lb(hibyte(n),t ? t|R_HIGH : 0);
945 /*)Function VOID out_rw(n)
949 * The function out_rw() outputs the relocation (R)
950 * data word as two bytes ordered according to hilo.
953 * int * relp pointer to rel array
959 * int lobyte() asout.c
960 * int hibyte() asout.c
963 * Pointer to relocation buffer incremented by 2.
978 /*)Function VOID out_tw(n)
982 * The function out_tw() outputs the text (T)
983 * data word as two bytes ordered according to hilo.
986 * int * txtp pointer to txt array
992 * int lobyte() asout.c
993 * int hibyte() asout.c
996 * Pointer to relocation buffer incremented by 2.
1003 *txtp++ = hibyte(n);
1004 *txtp++ = lobyte(n);
1006 *txtp++ = lobyte(n);
1007 *txtp++ = hibyte(n);
1011 /*)Function int lobyte(n)
1015 * The function lobyte() returns the lower byte of
1037 /*)Function int hibyte(n)
1041 * The function hibyte() returns the higher byte of
1060 return ((n>>8)&0377);