* asranlib/asranlib.c, link/lkar.h, link/lkar.c:
[fw/sdcc] / as / z80 / asout.c
1 /* asout.c
2
3    Copyright (C) 1989-1995 Alan R. Baldwin
4    721 Berkeley St., Kent, Ohio 44240
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
18
19 /*
20  * 10-Nov-07 borutr:
21  *           - applied changes from 28-Oct-97 JLH:
22  *             - outsym: show s_id as string rather than array [NCPS]
23  */
24
25 #include <stdio.h>
26 #include <setjmp.h>
27 #include <string.h>
28 #include "asm.h"
29
30
31 /*)Module       asout.c
32  *
33  *      The module asout.c contains all the functions used to
34  *      generate the .REL assembler output file.
35  *
36  *
37  *      The  assemblers' output object file is an ascii file containing
38  *      the information needed by the linker  to  bind  multiple  object
39  *      modules into a complete loadable memory image.
40  *
41  *      The object module contains the following designators:
42  *
43  *              [XDQ][HL]
44  *                      X        Hexidecimal radix
45  *                      D        Decimal radix
46  *                      Q        Octal radix
47  *
48  *                      H        Most significant byte first
49  *                      L        Least significant byte first
50  *
51  *              H        Header
52  *              M        Module
53  *              A        Area
54  *              S        Symbol
55  *              T        Object code
56  *              R        Relocation information
57  *              P        Paging information
58  *
59  *
60  *      (1)     Radix Line
61  *
62  *      The  first  line  of  an object module contains the [XDQ][HL]
63  *      format specifier (i.e.  XH indicates  a  hexidecimal  file  with
64  *      most significant byte first) for the following designators.
65  *
66  *
67  *      (2)     Header Line
68  *
69  *              H aa areas gg global symbols
70  *
71  *      The  header  line  specifies  the number of areas(aa) and the
72  *      number of global symbols(gg) defined or referenced in  this  ob-
73  *      ject module segment.
74  *
75  *
76  *      (3)     Module Line
77  *
78  *              M name
79  *
80  *      The  module  line  specifies  the module name from which this
81  *      header segment was assembled.  The module line will  not  appear
82  *      if the .module directive was not used in the source program.
83  *
84  *
85  *      (4)     Symbol Line
86  *
87  *              S string Defnnnn
88  *
89  *                      or
90  *
91  *              S string Refnnnn
92  *
93  *      The  symbol line defines (Def) or references (Ref) the symbol
94  *      'string' with the value nnnn.  The defined value is relative  to
95  *      the  current area base address.  References to constants and ex-
96  *      ternal global symbols will always appear before the  first  area
97  *      definition.  References to external symbols will have a value of
98  *      zero.
99  *
100  *
101  *      (5)     Area Line
102  *
103  *              A label size ss flags ff
104  *
105  *      The  area  line  defines the area label, the size (ss) of the
106  *      area in bytes, and the area flags (ff).  The area flags  specify
107  *      the ABS, REL, CON, OVR, and PAG parameters:
108  *
109  *              OVR/CON (0x04/0x00 i.e.  bit position 2)
110  *
111  *              ABS/REL (0x08/0x00 i.e.  bit position 3)
112  *
113  *              PAG (0x10 i.e.  bit position 4)
114  *
115  *
116  *      (6)     T Line
117  *
118  *              T xx xx nn nn nn nn nn ...
119  *
120  *      The  T  line contains the assembled code output by the assem-
121  *      bler with xx xx being the offset address from the  current  area
122  *      base address and nn being the assembled instructions and data in
123  *      byte format.
124  *
125  *
126  *      (7)     R Line
127  *
128  *              R 0 0 nn nn n1 n2 xx xx ...
129  *
130  *      The R line provides the relocation information to the linker.
131  *      The nn nn value is the current area index, i.e.  which area  the
132  *      current  values  were  assembled.  Relocation information is en-
133  *      coded in groups of 4 bytes:
134  *
135  *      1.  n1 is the relocation mode and object format
136  *              1.  bit 0 word(0x00)/byte(0x01)
137  *              2.  bit 1 relocatable area(0x00)/symbol(0x02)
138  *              3.  bit 2 normal(0x00)/PC relative(0x04) relocation
139  *              4.  bit  3  1-byte(0x00)/2-byte(0x08) object format for
140  *                  byte data
141  *              5.  bit 4 signed(0x00)/unsigned(0x10) byte data
142  *              6.  bit 5 normal(0x00)/page '0'(0x20) reference
143  *              7.  bit 6 normal(0x00)/page 'nnn'(0x40) reference
144  *              8.  bit 7 normal(0x00)/MSB of value
145  *
146  *      2.  n2  is  a byte index into the corresponding (i.e.  pre-
147  *              ceeding) T line data (i.e.  a pointer to the data to be
148  *              updated  by  the  relocation).   The T line data may be
149  *              1-byte or  2-byte  byte  data  format  or  2-byte  word
150  *              format.
151  *
152  *      3.  xx xx  is the area/symbol index for the area/symbol be-
153  *              ing referenced.  the corresponding area/symbol is found
154  *              in the header area/symbol lists.
155  *
156  *
157  *      The groups of 4 bytes are repeated for each item requiring relo-
158  *      cation in the preceeding T line.
159  *
160  *
161  *      (8)     P Line
162  *
163  *              P 0 0 nn nn n1 n2 xx xx
164  *
165  *      The  P  line provides the paging information to the linker as
166  *      specified by a .setdp directive.  The format of  the  relocation
167  *      information is identical to that of the R line.  The correspond-
168  *      ing T line has the following information:
169  *              T xx xx aa aa bb bb
170  *
171  *      Where  aa aa is the area reference number which specifies the
172  *      selected page area and bb bb is the base address  of  the  page.
173  *      bb bb will require relocation processing if the 'n1 n2 xx xx' is
174  *      specified in the P line.  The linker will verify that  the  base
175  *      address is on a 256 byte boundary and that the page length of an
176  *      area defined with the PAG type is not larger than 256 bytes.
177  *
178  *      The  linker  defaults any direct page references to the first
179  *      area defined in the input REL file.  All ASxxxx assemblers  will
180  *      specify the _CODE area first, making this the default page area.
181  *
182  *
183  *      asout.c contains the following functions:
184  *              int     lobyte()
185  *              int     hibyte()
186  *              VOID    out()
187  *              VOID    outab()
188  *              VOID    outall()
189  *              VOID    outarea()
190  *              VOID    outaw()
191  *              VOID    outbuf()
192  *              VOID    outchk()
193  *              VOID    outdot()
194  *              VOID    outdp()
195  *              VOID    outgsd()
196  *              VOID    outrb()
197  *              VOID    outrw()
198  *              VOID    outsym()
199  *              VOID    out_lb()
200  *              VOID    out_lw()
201  *              VOID    out_rw()
202  *              VOID    out_tw()
203  *
204  *      The module asout.c contains the following local variables:
205  *              int     rel[]           relocation data for code/data array
206  *              int *   relp            pointer to rel array
207  *              int     txt[]           assembled code/data array
208  *              int *   txtp            pointer to txt array
209  */
210
211 #define  NTXT   16
212 #define  NREL   16
213
214 char     txt[NTXT];
215 char     rel[NREL];
216
217 char    *txtp = { &txt[0] };
218 char    *relp = { &rel[0] };
219
220 /*)Function     VOID    outab(b)
221  *
222  *              int     b               assembler data word
223  *
224  *      The function outab() processes a single word of
225  *      assembled data in absolute format.
226  *
227  *      local variables:
228  *              int *   txtp            pointer to data word
229  *
230  *      global variables:
231  *              int     oflag           -o, generate relocatable output flag
232  *              int     pass            assembler pass number
233  *
234  *      functions called:
235  *              VOID    outchk()        asout.c
236  *              VOID    out_lb()        asout.c
237  *
238  *      side effects:
239  *              The current assembly address is incremented by 1.
240  */
241
242 VOID
243 outab(int b)
244 {
245         if (pass == 2) {
246                 out_lb(b,0);
247                 if (oflag) {
248                         outchk(1, 0);
249                         *txtp++ = lobyte(b);
250                 }
251         }
252         ++dot.s_addr;
253 }
254
255 /*)Function     VOID    outaw(w)
256  *
257  *              int     w               assembler data word
258  *
259  *      The function outaw() processes a single word of
260  *      assembled data in absolute format.
261  *
262  *      local variables:
263  *              int *   txtp            pointer to data word
264  *
265  *      global variables:
266  *              int     oflag           -o, generate relocatable output flag
267  *              int     pass            assembler pass number
268  *
269  *      functions called:
270  *              VOID    outchk()        asout.c
271  *              VOID    out_lw()        asout.c
272  *
273  *      side effects:
274  *              The current assembly address is incremented by 2.
275  */
276
277 VOID
278 outaw(int w)
279 {
280         if (pass == 2) {
281                 out_lw(w,0);
282                 if (oflag) {
283                         outchk(2, 0);
284                         out_tw(w);
285                 }
286         }
287         dot.s_addr += 2;
288 }
289
290 /*)Function     VOID    outrb(esp, r)
291  *
292  *              expr *  esp             pointer to expr structure
293  *              int     r               relocation mode
294  *
295  *      The function outrb() processes a byte of generated code
296  *      in either absolute or relocatable format dependent upon
297  *      the data contained in the expr structure esp.  If the
298  *      .REL output is enabled then the appropriate information
299  *      is loaded into the txt and rel buffers.
300  *
301  *      local variables:
302  *              int     n               symbol/area reference number
303  *              int *   relp            pointer to rel array
304  *              int *   txtp            pointer to txt array
305  *
306  *      global variables:
307  *              sym     dot             defined as sym[0]
308  *              int     oflag           -o, generate relocatable output flag
309  *              int     pass            assembler pass number
310  *
311  *      functions called:
312  *              VOID    aerr()          assubr.c
313  *              VOID    outchk()        asout.c
314  *              VOID    out_lb()        asout.c
315  *              VOID    out_rb()        asout.c
316  *              VOID    out_tb()        asout.c
317  *
318  *      side effects:
319  *              The current assembly address is incremented by 1.
320  */
321
322 VOID
323 outrb(struct expr *esp, int r)
324 {
325         register int n;
326
327         if (pass == 2) {
328                 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
329                         out_lb(lobyte(esp->e_addr),0);
330                         if (oflag) {
331                                 outchk(1, 0);
332                                 *txtp++ = lobyte(esp->e_addr);
333                         }
334                 } else {
335                         r |= R_BYTE | R_BYT2 | esp->e_rlcf;
336                         if (r & R_MSB) {
337                                 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
338                         } else {
339                                 out_lb(lobyte(esp->e_addr),r|R_RELOC);
340                         }
341                         if (oflag) {
342                                 outchk(2, 4);
343                                 out_tw(esp->e_addr);
344                                 if (esp->e_flag) {
345                                         n = esp->e_base.e_sp->s_ref;
346                                         r |= R_SYM;
347                                 } else {
348                                         n = esp->e_base.e_ap->a_ref;
349                                 }
350                                 *relp++ = r;
351                                 *relp++ = txtp - txt - 2;
352                                 out_rw(n);
353                         }
354                 }
355         }
356         ++dot.s_addr;
357 }
358
359 /*)Function     VOID    outrw(esp, r)
360  *
361  *              expr *  esp             pointer to expr structure
362  *              int     r               relocation mode
363  *
364  *      The function outrw() processes a word of generated code
365  *      in either absolute or relocatable format dependent upon
366  *      the data contained in the expr structure esp.  If the
367  *      .REL output is enabled then the appropriate information
368  *      is loaded into the txt and rel buffers.
369  *
370  *      local variables:
371  *              int     n               symbol/area reference number
372  *              int *   relp            pointer to rel array
373  *              int *   txtp            pointer to txt array
374  *
375  *      global variables:
376  *              sym     dot             defined as sym[0]
377  *              int     oflag           -o, generate relocatable output flag
378  *              int     pass            assembler pass number
379  *
380  *      functions called:
381  *              VOID    aerr()          assubr.c
382  *              VOID    outchk()        asout.c
383  *              VOID    out_lw()        asout.c
384  *              VOID    out_rw()        asout.c
385  *              VOID    out_tw()        asout.c
386  *
387  *      side effects:
388  *              The current assembly address is incremented by 2.
389  */
390
391 VOID
392 outrw(struct expr *esp, int r)
393 {
394         register int n;
395
396         if (pass == 2) {
397                 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
398                         out_lw(esp->e_addr,0);
399                         if (oflag) {
400                                 outchk(2, 0);
401                                 out_tw(esp->e_addr);
402                         }
403                 } else {
404                         r |= R_WORD | esp->e_rlcf;
405                         if (r & R_BYT2) {
406                                 rerr();
407                                 if (r & R_MSB) {
408                                         out_lw(hibyte(esp->e_addr),r|R_RELOC);
409                                 } else {
410                                         out_lw(lobyte(esp->e_addr),r|R_RELOC);
411                                 }
412                         } else {
413                                 out_lw(esp->e_addr,r|R_RELOC);
414                         }
415                         if (oflag) {
416                                 outchk(2, 4);
417                                 out_tw(esp->e_addr);
418                                 if (esp->e_flag) {
419                                         n = esp->e_base.e_sp->s_ref;
420                                         r |= R_SYM;
421                                 } else {
422                                         n = esp->e_base.e_ap->a_ref;
423                                 }
424                                 *relp++ = r;
425                                 *relp++ = txtp - txt - 2;
426                                 out_rw(n);
427                         }
428                 }
429         }
430         dot.s_addr += 2;
431 }
432
433 /*)Function     VOID    outdp(carea, esp)
434  *
435  *              area *  carea           pointer to current area strcuture
436  *              expr *  esp             pointer to expr structure
437  *
438  *      The function outdp() flushes the output buffer and
439  *      outputs paging information to the .REL file.
440  *
441  *      local variables:
442  *              int     n               symbol/area reference number
443  *              int     r               relocation mode
444  *              int *   relp            pointer to rel array
445  *              int *   txtp            pointer to txt array
446  *
447  *      global variables:
448  *              int     oflag           -o, generate relocatable output flag
449  *              int     pass            assembler pass number
450  *
451  *      functions called:
452  *              VOID    outbuf()        asout.c
453  *              VOID    outchk()        asout.c
454  *              VOID    out_rw()        asout.c
455  *              VOID    out_tw()        asout.c
456  *
457  *      side effects:
458  *              Output buffer flushed to .REL fiel.
459  *              Paging information dumped to .REL file.
460  */
461
462 VOID
463 outdp(struct area *carea, struct expr *esp)
464 {
465         register int n, r;
466
467         if (oflag && pass==2) {
468                 outchk(HUGE,HUGE);
469                 out_tw(carea->a_ref);
470                 out_tw(esp->e_addr);
471                 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
472                         r = R_WORD;
473                         if (esp->e_flag) {
474                                 n = esp->e_base.e_sp->s_ref;
475                                 r |= R_SYM;
476                         } else {
477                                 n = esp->e_base.e_ap->a_ref;
478                         }
479                         *relp++ = r;
480                         *relp++ = txtp - txt - 2;
481                         out_rw(n);
482                 }
483                 outbuf("P");
484         }
485 }
486
487 /*)Function     VOID    outall()
488  *
489  *      The function outall() will output any bufferred assembled
490  *      data and relocation information (during pass 2 if the .REL
491  *      output has been enabled).
492  *
493  *      local variables:
494  *              none
495  *
496  *      global variables:
497  *              int     oflag           -o, generate relocatable output flag
498  *              int     pass            assembler pass number
499  *
500  *      functions called:
501  *              VOID    outbuf()        asout.c
502  *
503  *      side effects:
504  *              assembled data and relocation buffers will be cleared.
505  */
506
507 VOID
508 outall(void)
509 {
510         if (oflag && pass==2)
511                 outbuf("R");
512 }
513
514 /*)Function     VOID    outdot()
515  *
516  *      The function outdot() outputs information about the
517  *      current program counter value (during pass 2 if the .REL
518  *      output has been enabled).
519  *
520  *      local variables:
521  *              none
522  *
523  *      global variables:
524  *              int     oflag           -o, generate relocatable output flag
525  *              int     pass            assembler pass number
526  *
527  *      functions called:
528  *              int     fprintf()       c_library
529  *              VOID    out()           asout.c
530  *
531  *      side effects:
532  *              assembled data and relocation buffers will be cleared.
533  */
534
535 VOID
536 outdot(void)
537 {
538         if (oflag && pass==2) {
539                 fprintf(ofp, "T");
540                 out(txt,(int) (txtp-txt));
541                 fprintf(ofp, "\n");
542                 fprintf(ofp, "R");
543                 out(rel,(int) (relp-rel));
544                 fprintf(ofp, "\n");
545                 txtp = txt;
546                 relp = rel;
547         }
548 }
549
550 /*)Function     outchk(nt, nr)
551  *
552  *              int     nr              number of additional relocation words
553  *              int     nt              number of additional data words
554  *
555  *      The function outchk() checks the data and relocation buffers
556  *      for space to insert the nt data words and nr relocation words.
557  *      If space is not available then output the current data and
558  *      initialize the data buffers to receive the new data.
559  *
560  *      local variables:
561  *              area *  ap              pointer to an area structure
562  *              int *   relp            pointer to rel array
563  *              int *   txtp            pointer to txt array
564  *
565  *      global variables:
566  *              sym     dot             defined as sym[0]
567  *
568  *      functions called:
569  *              VOID    outbuf()        asout.c
570  *
571  *      side effects:
572  *              Data and relocation buffers may be emptied and initialized.
573  */
574
575 VOID
576 outchk(int nt, int nr)
577 {
578         register struct area *ap;
579
580         if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
581                 outbuf("R");
582         }
583         if (txtp == txt) {
584                 out_tw(dot.s_addr);
585                 if ((ap = dot.s_area) != NULL) {
586                         *relp++ = R_WORD|R_AREA;
587                         *relp++ = 0;
588                         out_rw(ap->a_ref);
589                 }
590         }
591 }
592
593 /*)Function     VOID    outbuf()
594  *
595  *      The function outbuf() will output any bufferred data
596  *      and relocation information to the .REL file.  The output
597  *      buffer pointers and counters are initialized.
598  *
599  *      local variables:
600  *              int     rel[]           relocation data for code/data array
601  *              int *   relp            pointer to rel array
602  *              int     txt[]           assembled code/data array
603  *              int *   txtp            pointer to txt array
604  *
605  *      global variables:
606  *              FILE *  ofp             relocation output file handle
607  *
608  *      functions called:
609  *              VOID    out()           asout.c
610  *
611  *      side effects:
612  *              All bufferred data written to .REL file and
613  *              buffer pointers and counters initialized.
614  */
615
616 VOID
617 outbuf(char *s)
618 {
619         if (txtp > &txt[2]) {
620                 fprintf(ofp, "T");
621                 out(txt,(int) (txtp-txt));
622                 fprintf(ofp, "\n");
623                 fprintf(ofp, "%s", s);
624                 out(rel,(int) (relp-rel));
625                 fprintf(ofp, "\n");
626         }
627         txtp = txt;
628         relp = rel;
629 }
630
631 /*)Function     VOID    outgsd()
632  *
633  *      The function outgsd() performs the following:
634  *      (1)     outputs the .REL file radix
635  *      (2)     outputs the header specifying the number
636  *              of areas and global symbols
637  *      (3)     outputs the module name
638  *      (4)     set the reference number and output a symbol line
639  *              for all external global variables and absolutes
640  *      (5)     output an area name, set reference number and output
641  *              a symbol line for all global relocatables in the area.
642  *              Repeat this proceedure for all areas.
643  *
644  *      local variables:
645  *              area *  ap              pointer to an area structure
646  *              sym *   sp              pointer to a sym structure
647  *              int     i               loop counter
648  *              int     j               loop counter
649  *              int     c               string character value
650  *              int     narea           number of code areas
651  *              char *  ptr             string pointer
652  *              int     nglob           number of global symbols
653  *              int     rn              symbol reference number
654  *
655  *      global variables:
656  *              area *  areap           pointer to an area structure
657  *              char    module[]        module name string
658  *              sym * symhash[]         array of pointers to NHASH
659  *                                      linked symbol lists
660  *              int     xflag           -x, listing radix flag
661  *
662  *      functions called:
663  *              int     fprintf()       c_library
664  *              VOID    outarea()       asout.c
665  *              VOID    outsym()        asout.c
666  *              int     putc()          c_library
667  *
668  *      side effects:
669  *              All symbols are given reference numbers, all symbol
670  *              and area information is output to the .REL file.
671  */
672
673 VOID
674 outgsd(void)
675 {
676         register struct area *ap;
677         register struct sym  *sp;
678         register int i, j;
679         char *ptr;
680         int c, narea, nglob, rn;
681
682         /*
683          * Number of areas
684          */
685         narea = areap->a_ref + 1;
686
687         /*
688          * Number of global references/absolutes
689          */
690         nglob = 0;
691         for (i = 0; i < NHASH; ++i) {
692                 sp = symhash[i];
693                 while (sp) {
694                         if (sp->s_flag&S_GBL)
695                                 ++nglob;
696                         sp = sp->s_sp;
697                 }
698         }
699
700         /*
701          * Output Radix and number of areas and symbols
702          */
703         if (xflag == 0) {
704                 fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
705                 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
706         } else
707         if (xflag == 1) {
708                 fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
709                 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
710         } else
711         if (xflag == 2) {
712                 fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
713                 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
714         }
715
716         /*
717          * Module name
718          */
719         if (module[0]) {
720                 fprintf(ofp, "M ");
721                 ptr = &module[0];
722                 while (ptr < &module[NCPS]) {
723                         if ((c = *ptr++) != 0)
724                                 putc(c, ofp);
725                 }
726                 putc('\n', ofp);
727         }
728
729     /*
730      * Sdcc compile options
731      */
732         if (strlen(optsdcc)) fprintf(ofp, "O %s\n", optsdcc);
733
734         /*
735          * Global references and absolutes.
736          */
737         rn = 0;
738         for (i=0; i<NHASH; ++i) {
739                 sp = symhash[i];
740                 while (sp) {
741                         if (sp->s_area==NULL && sp->s_flag&S_GBL) {
742                                 sp->s_ref = rn++;
743                                 outsym(sp);
744                         }
745                         sp = sp->s_sp;
746                 }
747         }
748
749         /*
750          * Global relocatables.
751          */
752         for (i=0; i<narea; ++i) {
753                 ap = areap;
754                 while (ap->a_ref != i)
755                         ap = ap->a_ap;
756                 outarea(ap);
757                 for (j=0; j<NHASH; ++j) {
758                         sp = symhash[j];
759                         while (sp) {
760                                 if (sp->s_area==ap && sp->s_flag&S_GBL) {
761                                         sp->s_ref = rn++;
762                                         outsym(sp);
763                                 }
764                                 sp = sp->s_sp;
765                         }
766                 }
767         }
768 }
769
770 /*)Function     VOID    outarea(ap)
771  *
772  *              area *  ap              pointer to an area structure
773  *
774  *      The function outarea()  outputs the A line to the .REL
775  *      file.  The A line contains the area's name, size, and
776  *      attributes.
777  *
778  *      local variables:
779  *              char *  ptr             pointer to area id string
780  *              int     c               character value
781  *
782  *      global variables:
783  *              FILE *  ofp             relocation output file handle
784  *              int     xflag           -x, listing radix flag
785  *
786  *      functions called:
787  *              int     fprintf()       c_library
788  *              int     putc()          c_library
789  *
790  *      side effects:
791  *              The A line is sent to the .REL file.
792  */
793
794 VOID
795 outarea(struct area *ap)
796 {
797         fprintf(ofp, "A %s", ap->a_id);
798         if (xflag == 0) {
799                 fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
800         } else
801         if (xflag == 1) {
802                 fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
803         } else
804         if (xflag == 2) {
805                 fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
806         }
807 }
808
809 /*)Function     VOID    outsym(sp)
810  *
811  *              sym *   sp              pointer to a sym structure
812  *
813  *      The function outsym() outputs the S line to the .REL
814  *      file.  The S line contains the symbols name and whether the
815  *      the symbol is defined or referenced.
816  *
817  *      local variables:
818  *              char *  ptr             pointer to symbol id string
819  *              int     c               character value
820  *
821  *      global variables:
822  *              FILE *  ofp             relocation output file handle
823  *              int     xflag           -x, listing radix flag
824  *
825  *      functions called:
826  *              int     fprintf()       c_library
827  *              int     putc()          c_library
828  *
829  *      side effects:
830  *              The S line is sent to the .REL file.
831  */
832
833 VOID
834 outsym(struct sym *sp)
835 {
836         fprintf(ofp, "S %s", sp->s_id);
837         fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
838         if (xflag == 0) {
839                 fprintf(ofp, "%04X\n", sp->s_addr);
840         } else
841         if (xflag == 1) {
842                 fprintf(ofp, "%06o\n", sp->s_addr);
843         } else
844         if (xflag == 2) {
845                 fprintf(ofp, "%05u\n", sp->s_addr);
846         }
847 }
848
849 /*)Function     VOID    out(p, n)
850  *
851  *              int     n               number of words to output
852  *              int *   p               pointer to data words
853  *
854  *      The function out() outputs the data words to the .REL file
855  *      int the specified radix.
856  *
857  *      local variables:
858  *              none
859  *
860  *      global variables:
861  *              FILE *  ofp             relocation output file handle
862  *              int     xflag           -x, listing radix flag
863  *
864  *      functions called:
865  *              int     fprintf()       c_library
866  *
867  *      side effects:
868  *              Data is sent to the .REL file.
869  */
870
871 VOID
872 out(char *p, int n)
873 {
874         while (n--) {
875                 if (xflag == 0) {
876                         fprintf(ofp, " %02X", (*p++)&0377);
877                 } else
878                 if (xflag == 1) {
879                         fprintf(ofp, " %03o", (*p++)&0377);
880                 } else
881                 if (xflag == 2) {
882                         fprintf(ofp, " %03u", (*p++)&0377);
883                 }
884         }
885 }
886
887 /*)Function     VOID    out_lb(b, t)
888  *
889  *              int     b               assembled data
890  *              int     t               relocation type
891  *
892  *      The function out_lb() copies the assembled data and
893  *      its relocation type to the list data buffers.
894  *
895  *      local variables:
896  *              none
897  *
898  *      global variables:
899  *              int *   cp              pointer to assembler output array cb[]
900  *              int *   cpt             pointer to assembler relocation type
901  *                                      output array cbt[]
902  *
903  *      functions called:
904  *              none
905  *
906  *      side effects:
907  *              Pointers to data and relocation buffers incremented by 1.
908  */
909
910 VOID
911 out_lb(int b,int t)
912 {
913         if (cp < &cb[NCODE]) {
914                 *cp++ = b;
915                 *cpt++ = t;
916         }
917 }
918
919 /*)Function     VOID    out_lw(n, t)
920  *
921  *              int     n               assembled data
922  *              int     t               relocation type
923  *
924  *      The function out_lw() copies the assembled data and
925  *      its relocation type to the list data buffers.
926  *
927  *      local variables:
928  *              none
929  *
930  *      global variables:
931  *              int *   cp              pointer to assembler output array cb[]
932  *              int *   cpt             pointer to assembler relocation type
933  *                                      output array cbt[]
934  *
935  *      functions called:
936  *              none
937  *
938  *      side effects:
939  *              Pointers to data and relocation buffers incremented by 2.
940  */
941
942 VOID
943 out_lw(int n,int t)
944 {
945         if (hilo) {
946                 out_lb(hibyte(n),t ? t|R_HIGH : 0);
947                 out_lb(lobyte(n),t);
948         } else {
949                 out_lb(lobyte(n),t);
950                 out_lb(hibyte(n),t ? t|R_HIGH : 0);
951         }
952 }
953
954 /*)Function     VOID    out_rw(n)
955  *
956  *              int     n               data word
957  *
958  *      The function out_rw() outputs the relocation (R)
959  *      data word as two bytes ordered according to hilo.
960  *
961  *      local variables:
962  *              int *   relp            pointer to rel array
963  *
964  *      global variables:
965  *              none
966  *
967  *      functions called:
968  *              int     lobyte()        asout.c
969  *              int     hibyte()        asout.c
970  *
971  *      side effects:
972  *              Pointer to relocation buffer incremented by 2.
973  */
974
975 VOID
976 out_rw(int n)
977 {
978         if (hilo) {
979                 *relp++ = hibyte(n);
980                 *relp++ = lobyte(n);
981         } else {
982                 *relp++ = lobyte(n);
983                 *relp++ = hibyte(n);
984         }
985 }
986
987 /*)Function     VOID    out_tw(n)
988  *
989  *              int     n               data word
990  *
991  *      The function out_tw() outputs the text (T)
992  *      data word as two bytes ordered according to hilo.
993  *
994  *      local variables:
995  *              int *   txtp            pointer to txt array
996  *
997  *      global variables:
998  *              none
999  *
1000  *      functions called:
1001  *              int     lobyte()        asout.c
1002  *              int     hibyte()        asout.c
1003  *
1004  *      side effects:
1005  *              Pointer to relocation buffer incremented by 2.
1006  */
1007
1008 VOID
1009 out_tw(int n)
1010 {
1011         if (hilo) {
1012                 *txtp++ = hibyte(n);
1013                 *txtp++ = lobyte(n);
1014         } else {
1015                 *txtp++ = lobyte(n);
1016                 *txtp++ = hibyte(n);
1017         }
1018 }
1019
1020 /*)Function     int     lobyte(n)
1021  *
1022  *              int     n               data word
1023  *
1024  *      The function lobyte() returns the lower byte of
1025  *      integer n.
1026  *
1027  *      local variables:
1028  *              none
1029  *
1030  *      global variables:
1031  *              none
1032  *
1033  *      functions called:
1034  *              none
1035  *
1036  *      side effects:
1037  *              none
1038  */
1039
1040 int
1041 lobyte(int n)
1042 {
1043         return (n&0377);
1044 }
1045
1046 /*)Function     int     hibyte(n)
1047  *
1048  *              int     n               data word
1049  *
1050  *      The function hibyte() returns the higher byte of
1051  *      integer n.
1052  *
1053  *      local variables:
1054  *              none
1055  *
1056  *      global variables:
1057  *              none
1058  *
1059  *      functions called:
1060  *              none
1061  *
1062  *      side effects:
1063  *              none
1064  */
1065
1066 int
1067 hibyte(int n)
1068 {
1069         return ((n>>8)&0377);
1070 }
1071