4 * Copyright (C) 1989-2009 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
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.
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/>.
28 * - lstarea: show s_id as string rather than array [NCPS]
29 * - lstarea: show a_id as string rather than array [NCPS]
30 * 31-Oct-97 JLH: add NoICE output file genration in lstarea
31 * 02-Apr-98 JLH: add XDATA, DATA, BIT flags to area output
38 * The module lklist.c contains the functions which
39 * output the linker .map file and produce a relocated
42 * lklist.c contains the following functions:
51 * lklist.c contains no local variables.
54 /*)Function VOID newpag()
56 * The function newpag() outputs a page skip, writes the
57 * first page header line, sets the line count to 1, and
58 * increments the page counter.
64 * int lop current line number on page
65 * int page current page number
68 * int fprintf() c_library
71 * The page and line counters are updated.
77 fprintf(fp
, "\fASxxxx Linker %s, page %u.\n", VERSION
, ++page
);
81 /*)Function int dgt(rdx,str,n)
83 * int rdx radix bit code
84 * char *str pointer to the test string
85 * int n number of characters to check
87 * The function dgt() verifies that the string under test
88 * is of the specified radix.
94 * ctype[] array of character types
104 dgt(int rdx
, char *str
, int n
)
108 for (i
=0; i
<n
; i
++) {
109 if ((ctype
[*str
++ & 0x007F] & rdx
) == 0)
115 /*)Function VOID slew(xp, yp)
117 * area * xp pointer to an area structure
118 * bank * yp pointer to a bank structure
120 * The function slew() increments the page line counter.
121 * If the number of lines exceeds the maximum number of
122 * lines per page then a page skip and a page header are
126 * a_uint ai temporary
127 * a_uint aj temporary
129 * int n repeat counter
130 * char * frmta temporary format specifier
131 * char * frmtb temporary format specifier
132 * char * ptr pointer to an id string
135 * int a_bytes T line address bytes
136 * int a_mask addressing mask
137 * int lop current line number on page
138 * FILE *mfp Map output file handle
139 * int wflag Wide format listing
140 * int xflag Map file radix type flag
143 * int fprintf() c_library
144 * VOID newpag() lklist.c
145 * char putc() c_library
148 * The page line and the page count may be updated.
152 slew(struct area
*xp
, struct bank
*yp
)
155 char *frmta
, *frmtb
, *ptr
;
162 case 0: frmta
= "Hexadecimal"; break;
163 case 1: frmta
= "Octal"; break;
164 case 2: frmta
= "Decimal"; break;
166 fprintf(mfp
, "%s [%d-Bits]\n", frmta
, a_bytes
*8);
168 fprintf(mfp
, "[ Bank == %s ]\n", yp
->b_id
);
176 " Size Decimal Bytes (Attributes)\n");
178 "-------------------------------- ----");
180 " ---- ------- ----- ------------\n");
185 " Size Decimal Bytes (Attributes)\n");
187 "-------------------- ---- ");
189 " ---- ------- ----- ------------\n");
192 ai
= xp
->a_addr
& a_mask
;
193 aj
= xp
->a_size
& a_mask
;
200 fprintf(mfp
, "%-32.32s", ptr
);
202 fprintf(mfp
, "%-19.19s", ptr
);
210 case 0: frmta
= " %04lX %04lX"; break;
211 case 1: frmta
= " %06lo %06lo"; break;
212 case 2: frmta
= " %05lu %05lu"; break;
214 frmtb
= " = %6lu. bytes "; break;
218 case 0: frmta
= " %06lX %06lX"; break;
219 case 1: frmta
= " %08lo %08lo"; break;
220 case 2: frmta
= " %08lu %08lu"; break;
222 frmtb
= " = %8lu. bytes "; break;
226 case 0: frmta
= " %08lX %08lX"; break;
227 case 1: frmta
= " %011lo %011lo"; break;
228 case 2: frmta
= " %010lu %010lu"; break;
230 frmtb
= " = %10lu. bytes "; break;
238 case 0: frmta
= " %04X %04X"; break;
239 case 1: frmta
= " %06o %06o"; break;
240 case 2: frmta
= " %05u %05u"; break;
242 frmtb
= " = %6u. bytes "; break;
246 case 0: frmta
= " %06X %06X"; break;
247 case 1: frmta
= " %08o %08o"; break;
248 case 2: frmta
= " %08u %08u"; break;
250 frmtb
= " = %8u. bytes "; break;
254 case 0: frmta
= " %08X %08X"; break;
255 case 1: frmta
= " %011o %011o"; break;
256 case 2: frmta
= " %010u %010u"; break;
258 frmtb
= " = %10u. bytes "; break;
261 fprintf(mfp
, frmta
, ai
, aj
);
262 fprintf(mfp
, frmtb
, aj
);
264 if (xp
->a_flag
& A3_ABS
) {
265 fprintf(mfp
, "(ABS");
267 fprintf(mfp
, "(REL");
269 if (xp
->a_flag
& A3_OVR
) {
270 fprintf(mfp
, ",OVR");
272 fprintf(mfp
, ",CON");
274 if (xp
->a_flag
& A3_PAG
) {
275 fprintf(mfp
, ",PAG");
279 if (xp
->a_flag
& A_CODE
) {
280 fprintf(mfp
, ",CODE");
282 if (xp
->a_flag
& A_XDATA
) {
283 fprintf(mfp
, ",XDATA");
285 if (xp
->a_flag
& A_BIT
) {
286 fprintf(mfp
, ",BIT");
288 /* end sdld specific */
296 " Global Defined In Module\n");
298 " ----- --------------------------------");
300 " ------------------------\n");
304 case 2: frmta
= " Value Global ";
305 frmtb
= " ----- ------ ";
308 case 4: frmta
= " Value Global ";
309 frmtb
= " ----- ------ ";
314 fprintf(mfp
, "%s", frmta
);
317 fprintf(mfp
, "%s", frmtb
);
326 /* Used for qsort call in lstsym */
327 static int _cmpSymByAddr(const void *p1
, const void *p2
)
329 struct sym
**s1
= (struct sym
**)(p1
);
330 struct sym
**s2
= (struct sym
**)(p2
);
331 int delta
= ((*s1
)->s_addr
+ (*s1
)->s_axp
->a_addr
) -
332 ((*s2
)->s_addr
+ (*s2
)->s_axp
->a_addr
);
334 /* Sort first by address, then by name. */
339 return strcmp((*s1
)->s_id
,(*s2
)->s_id
);
341 /* end sdld specific */
343 /*)Function VOID lstarea(xp, yp)
345 * area * xp pointer to an area structure
346 * bank * yp pointer to a bank structure
348 * The function lstarea() creates the linker map output for
349 * the area specified by pointer xp. The generated output
350 * area header includes the area name, starting address,
351 * size of area, number of words (in decimal), and the
352 * area attributes. The symbols defined in this area are
353 * sorted by ascending address and output four per line
354 * in the selected radix (one per line in wide format).
357 * areax * oxp pointer to an area extension structure
359 * int j bubble sort update status
360 * int n repeat counter
361 * char * frmt temporary format specifier
362 * char * ptr pointer to an id string
363 * int nmsym number of symbols in area
364 * a_uint a0 temporary
365 * a_uint ai temporary
366 * a_uint aj temporary
367 * sym * sp pointer to a symbol structure
368 * sym ** p pointer to an array of
369 * pointers to symbol structures
372 * int a_bytes T line address bytes
373 * FILE *mfp Map output file handle
374 * sym *symhash[NHASH] array of pointers to NHASH
375 * linked symbol lists
376 * int wflag Wide format listing
377 * int xflag Map file radix type flag
380 * int fprintf() c_library
381 * VOID free() c_library
382 * char * malloc() c_library
383 * char putc() c_library
384 * VOID slew() lklist.c
387 * Map output generated.
391 lstarea(struct area
*xp
, struct bank
*yp
)
402 /* end sdld specific */
405 * Find number of symbols in area
410 for (i
=0; i
<NHASH
; i
++) {
413 if (oxp
== sp
->s_axp
)
421 if ((nmsym
== 0) && (xp
->a_size
== 0)) {
433 * Allocate space for an array of pointers to symbols
436 if ( (p
= (struct sym
**) malloc (nmsym
*sizeof(struct sym
*))) == NULL
) {
437 fprintf(mfp
, "Insufficient space to build Map Segment.\n");
443 for (i
=0; i
<NHASH
; i
++) {
446 if (oxp
== sp
->s_axp
) {
457 * Quick Sort of Addresses in Symbol Table Array
459 qsort(p
, nmsym
, sizeof(struct sym
*), _cmpSymByAddr
);
462 * Bubble Sort of Addresses in Symbol Table Array
468 a0
= sp
->s_addr
+ sp
->s_axp
->a_addr
;
469 for (i
=1; i
<nmsym
; ++i
) {
471 ai
= sp
->s_addr
+ sp
->s_axp
->a_addr
;
487 case 2: n
= 4; break;
489 case 4: n
= 3; break;
493 * Symbol Table Output
496 memPage
= (xp
->a_flag
& A_CODE
) ? 0x0C : ((xp
->a_flag
& A_XDATA
) ? 0x0D : ((xp
->a_flag
& A_BIT
) ? 0x0B : 0x00));
497 /* end sdld specific */
505 case 2: frmt
= " "; break;
507 case 4: frmt
= ""; break;
510 fprintf(mfp
, "%s%X:", frmt
, memPage
);
512 fprintf(mfp
, "%s ", frmt
);
516 case 2: frmt
= " "; break;
518 case 4: frmt
= " "; break;
520 fprintf(mfp
, "%s", frmt
);
527 case 2: frmt
= " "; break;
529 case 4: frmt
= " "; break;
531 fprintf(mfp
, "%s", frmt
);
535 aj
= (sp
->s_addr
+ sp
->s_axp
->a_addr
) & a_mask
;
542 case 0: frmt
= " %04lX "; break;
543 case 1: frmt
= "%06lo "; break;
544 case 2: frmt
= " %05lu "; break;
550 case 0: frmt
= " %06lX "; break;
551 case 1: frmt
= " %08lo "; break;
552 case 2: frmt
= " %08lu "; break;
558 case 0: frmt
= " %08lX "; break;
559 case 1: frmt
= "%011lo "; break;
560 case 2: frmt
= " %010lu "; break;
570 case 0: frmt
= " %04X "; break;
571 case 1: frmt
= "%06o "; break;
572 case 2: frmt
= " %05u "; break;
578 case 0: frmt
= " %06X "; break;
579 case 1: frmt
= " %08o "; break;
580 case 2: frmt
= " %08u "; break;
586 case 0: frmt
= " %08X "; break;
587 case 1: frmt
= "%011o "; break;
588 case 2: frmt
= " %010u "; break;
593 fprintf(mfp
, frmt
, aj
);
599 * NoICE output of symbol
601 if (jflag
) DefineNoICE(ptr
, aj
, yp
);
606 * SDCDB output of symbol
608 if (yflag
) DefineSDCDB(ptr
, aj
);
612 fprintf(mfp
, "%-32.32s", ptr
);
616 fprintf(mfp
, " %-.28s", ptr
);
621 case 2: frmt
= "%-8.8s"; break;
623 case 4: frmt
= "%-9.9s"; break;
625 fprintf(mfp
, frmt
, ptr
);
630 if (wflag
|| (i
% n
== 0)) {
640 /*)Function VOID lkulist(i)
642 * int i i # 0 process LST to RST file
643 * i = 0 copy remainder of LST file
644 * to RST file and close files
646 * The function lkulist() creates a relocated listing (.rst)
647 * output file from the ASxxxx assembler listing (.lst)
648 * files. The .lst file's program address and code bytes
649 * are changed to reflect the changes made by ASlink as
650 * the .rel files are combined into a single relocated
654 * a_uint cpc current program counter address in PC increments
655 * int cbytes bytes so far in T line
658 * int a_bytes T Line Address Bytes
659 * int hilo byte order
660 * int gline get a line from the LST file
661 * to translate for the RST file
662 * a_uint pc current program counter address in bytes
663 * int pcb bytes per instruction word
664 * char rb[] read listing file text line
665 * FILE *rfp The file handle to the current
667 * int rtcnt count of data words
668 * int rtflg[] output the data flag
669 * a_uint rtval[] relocated data
670 * int rterr[] error flag ???
671 * FILE *tfp The file handle to the current
672 * LST file being scanned
675 * int fclose() c_library
676 * int fgets() c_library
677 * int fprintf() c_library
678 * VOID lkalist() lklist.c
679 * VOID lkglist() lklist.c
682 * A .rst file is created for each available .lst
683 * file associated with a .rel file.
693 * Exit if listing file is not open
699 * Normal processing of LST to RST
703 * Line with only address
705 if (rtcnt
== a_bytes
) {
709 * Line with address and code
714 for (i
=a_bytes
; i
< rtcnt
; i
++) {
716 lkglist(cpc
, (int) (rtval
[i
] & 0xFF), rterr
[i
]);
718 cpc
+= (cbytes
% pcb
) ? 0 : 1;
723 * Copy remainder of LST to RST
727 fprintf(rfp
, "%s", rb
);
729 while (fgets(rb
, sizeof(rb
)-2, tfp
) != 0) {
730 fprintf(rfp
, "%s", rb
);
739 /*)Function VOID lkalist(cpc)
741 * int cpc current program counter value
743 * The function lkalist() performs the following functions:
745 * (1) if the value of gline = 0 then the current listing
746 * file line is copied to the relocated listing file output.
748 * (2) the listing file is read line by line and copied to
749 * the relocated listing file until a valid source
750 * line number and a program counter value of the correct
751 * radix is found. The new relocated pc value is substituted
752 * and the line is written to the RST file.
756 * int m character count
757 * int n character index
758 * int r character radix
759 * char * frmt temporary format specifier
760 * char str[] temporary string
763 * int a_bytes T Line Address Bytes
764 * a_uint a_mask address masking parameter
765 * int gcntr data byte counter
766 * int gline get a line from the LST file
767 * to translate for the RST file
768 * char rb[] read listing file text line
769 * FILE *rfp The file handle to the current
771 * FILE *tfp The file handle to the current
772 * LST file being scanned
776 * int fclose() c_library
777 * int fgets() c_library
778 * int fprintf() c_library
779 * int sprintf() c_library
780 * char * strncpy() c_library
783 * Lines of the LST file are copied to the RST file,
784 * the last line copied has the code address
785 * updated to reflect the program relocation.
788 /* The Output Formats, No Cycle Count
790 11111111112222222222333333333344444-----
791 012345678901234567890123456789012345678901234-----
793 ee XXXX xx xx xx xx xx xx LLLLL ************* HEX(16)
794 ee 000000 ooo ooo ooo ooo LLLLL ************* OCTAL(16)
795 ee DDDDD ddd ddd ddd ddd LLLLL ************* DECIMAL(16)
801 11111111112222222222333333333344444-----
802 012345678901234567890123456789012345678901234-----
804 ee XXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(24)
805 ee OO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(24)
806 ee DDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(24)
812 11111111112222222222333333333344444-----
813 012345678901234567890123456789012345678901234-----
815 ee XXXXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(32)
816 eeOOOOO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(32)
817 ee DDDDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(32)
823 /* The Output Formats, With Cycle Count [nn]
825 11111111112222222222333333333344444-----
826 012345678901234567890123456789012345678901234-----
828 ee XXXX xx xx xx xx xx[nn]LLLLL ************* HEX(16)
829 ee 000000 ooo ooo ooo [nn]LLLLL ************* OCTAL(16)
830 ee DDDDD ddd ddd ddd [nn]LLLLL ************* DECIMAL(16)
836 11111111112222222222333333333344444-----
837 012345678901234567890123456789012345678901234-----
839 ee XXXXXX xx xx xx xx xx xx[nn]LLLLL ********* HEX(24)
840 ee OO000000 ooo ooo ooo ooo [nn]LLLLL ********* OCTAL(24)
841 ee DDDDDDDD ddd ddd ddd ddd [nn]LLLLL ********* DECIMAL(24)
847 11111111112222222222333333333344444-----
848 012345678901234567890123456789012345678901234-----
850 ee XXXXXXXX xx xx xx xx xx xx[nn]LLLLL ********* HEX(32)
851 eeOOOOO000000 ooo ooo ooo ooo [nn]LLLLL ********* OCTAL(32)
852 ee DDDDDDDDDD ddd ddd ddd ddd [nn]LLLLL ********* DECIMAL(32)
866 * Truncate (int) to N-Bytes
871 * Exit if listing file is not open
873 loop
: if (tfp
== NULL
)
877 * Copy current LST to RST
880 fprintf(rfp
, "%s", rb
);
885 * Clear text line buffer
887 memset(rb
, 0, sizeof(rb
));
890 * Get next LST text line
892 if (fgets(rb
, sizeof(rb
)-2, tfp
) == NULL
) {
901 * Must have an ASxxxx Listing line number
905 case 2: n
= 30; break;
907 case 4: n
= 38; break;
909 if (!dgt(RAD10
, &rb
[n
], 1)) {
910 fprintf(rfp
, "%s", rb
);
915 * Must have an address in the expected radix
924 case 2: n
= 3; m
= 4; frmt
= "%04lX"; break;
925 case 3: n
= 6; m
= 6; frmt
= "%06lX"; break;
926 case 4: n
= 4; m
= 8; frmt
= "%08lX"; break;
933 case 2: n
= 4; m
= 5; frmt
= "%05lu"; break;
934 case 3: n
= 5; m
= 8; frmt
= "%08lu"; break;
935 case 4: n
= 3; m
= 10; frmt
= "%010lu"; break;
942 case 2: n
= 3; m
= 6; frmt
= "%06lo"; break;
943 case 3: n
= 5; m
= 8; frmt
= "%08lo"; break;
944 case 4: n
= 2; m
= 11; frmt
= "%011lo"; break;
955 case 2: n
= 3; m
= 4; frmt
= "%04X"; break;
956 case 3: n
= 6; m
= 6; frmt
= "%06X"; break;
957 case 4: n
= 4; m
= 8; frmt
= "%08X"; break;
964 case 2: n
= 4; m
= 5; frmt
= "%05u"; break;
965 case 3: n
= 5; m
= 8; frmt
= "%08u"; break;
966 case 4: n
= 3; m
= 10; frmt
= "%010u"; break;
973 case 2: n
= 3; m
= 6; frmt
= "%06o"; break;
974 case 3: n
= 5; m
= 8; frmt
= "%08o"; break;
975 case 4: n
= 2; m
= 11; frmt
= "%011o"; break;
980 if (!dgt(r
, &rb
[n
], m
)) {
981 fprintf(rfp
, "%s", rb
);
984 sprintf(str
, frmt
, cpc
);
985 strncpy(&rb
[n
], str
, m
);
988 * Copy updated LST text line to RST
990 fprintf(rfp
, "%s", rb
);
994 /*)Function VOID lkglist(cpc,v,err)
996 * int cpc current program counter value
997 * int v value of byte at this address
998 * int err error flag for this value
1000 * The function lkglist() performs the following functions:
1002 * (1) if the value of gline = 1 then the listing file
1003 * is read line by line and copied to the
1004 * relocated listing file until a valid source
1005 * line number and a program counter value of the correct
1008 * (2) The new relocated values and code address are
1009 * substituted and the line may be written to the RST file.
1012 * int a string index for first byte
1013 * int i loop counter
1014 * int m character count
1015 * int n character index
1016 * int r character radix
1018 * int u repeat counter
1019 * char * afrmt temporary format specifier
1020 * char * frmt temporary format specifier
1021 * char str[] temporary string
1024 * int a_bytes T Line Address Bytes
1025 * a_uint a_mask address masking parameter
1026 * int gcntr data byte counter
1027 * set to -1 for a continuation line
1028 * int gline get a line from the LST file
1029 * to translate for the RST file
1030 * char rb[] read listing file text line
1031 * char *rp pointer to listing file text line
1032 * FILE *rfp The file handle to the current
1034 * FILE *tfp The file handle to the current
1035 * LST file being scanned
1036 * char *errmsg3[] array of pointers to error strings
1039 * int dgt() lklist.c
1040 * int fclose() c_library
1041 * int fgets() c_library
1042 * int fprintf() c_library
1043 * int sprintf() c_library
1044 * char * strncpy() c_library
1047 * Lines of the LST file are copied to the RST file
1048 * with updated data values and code addresses.
1051 /* The Output Formats, No Cycle Count
1053 11111111112222222222333333333344444-----
1054 012345678901234567890123456789012345678901234-----
1056 ee XXXX xx xx xx xx xx xx LLLLL ************* HEX(16)
1057 ee 000000 ooo ooo ooo ooo LLLLL ************* OCTAL(16)
1058 ee DDDDD ddd ddd ddd ddd LLLLL ************* DECIMAL(16)
1064 11111111112222222222333333333344444-----
1065 012345678901234567890123456789012345678901234-----
1067 ee XXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(24)
1068 ee OO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(24)
1069 ee DDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(24)
1075 11111111112222222222333333333344444-----
1076 012345678901234567890123456789012345678901234-----
1078 ee XXXXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(32)
1079 eeOOOOO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(32)
1080 ee DDDDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(32)
1086 /* The Output Formats, With Cycle Count [nn]
1088 11111111112222222222333333333344444-----
1089 012345678901234567890123456789012345678901234-----
1091 ee XXXX xx xx xx xx xx[nn]LLLLL ************* HEX(16)
1092 ee 000000 ooo ooo ooo [nn]LLLLL ************* OCTAL(16)
1093 ee DDDDD ddd ddd ddd [nn]LLLLL ************* DECIMAL(16)
1099 11111111112222222222333333333344444-----
1100 012345678901234567890123456789012345678901234-----
1102 ee XXXXXX xx xx xx xx xx xx[nn]LLLLL ********* HEX(24)
1103 ee OO000000 ooo ooo ooo ooo [nn]LLLLL ********* OCTAL(24)
1104 ee DDDDDDDD ddd ddd ddd ddd [nn]LLLLL ********* DECIMAL(24)
1110 11111111112222222222333333333344444-----
1111 012345678901234567890123456789012345678901234-----
1113 ee XXXXXXXX xx xx xx xx xx xx[nn]LLLLL ********* HEX(32)
1114 eeOOOOO000000 ooo ooo ooo ooo [nn]LLLLL ********* OCTAL(32)
1115 ee DDDDDDDDDD ddd ddd ddd ddd [nn]LLLLL ********* DECIMAL(32)
1122 lkglist(a_uint cpc
, int v
, int err
)
1126 int a
, n
, m
, r
, s
, u
;
1129 * Truncate (int) to N-Bytes
1134 * Exit if listing file is not open
1136 loop
: if (tfp
== NULL
)
1140 * Get next LST text line
1144 * Clear text line buffer
1146 memset(rb
, 0, sizeof(rb
));
1149 * Get next LST text line
1151 if (fgets(rb
, sizeof(rb
)-2, tfp
) == NULL
) {
1160 * Check for a listing line number if required
1165 case 2: n
= 30; break;
1167 case 4: n
= 38; break;
1169 if (!dgt(RAD10
, &rb
[n
], 1)) {
1170 fprintf(rfp
, "%s", rb
);
1188 case 2: a
= 8; s
= 3; n
= 3; m
= 4; u
= 6; afrmt
= "%04lX"; break;
1189 case 3: a
= 13; s
= 3; n
= 6; m
= 6; u
= 7; afrmt
= "%06lX"; break;
1190 case 4: a
= 13; s
= 3; n
= 4; m
= 8; u
= 7; afrmt
= "%08lX"; break;
1192 frmt
= " %02X"; break;
1197 case 2: a
= 10; s
= 4; n
= 4; m
= 5; u
= 4; afrmt
= "%05lu"; break;
1198 case 3: a
= 14; s
= 4; n
= 5; m
= 8; u
= 5; afrmt
= "%08lu"; break;
1199 case 4: a
= 14; s
= 4; n
= 3; m
= 10; u
= 5; afrmt
= "%010lu"; break;
1201 frmt
= " %03u"; break;
1206 case 2: a
= 10; s
= 4; n
= 3; m
= 6; u
= 4; afrmt
= "%06lo"; break;
1207 case 3: a
= 14; s
= 4; n
= 5; m
= 8; u
= 5; afrmt
= "%08lo"; break;
1208 case 4: a
= 14; s
= 4; n
= 2; m
= 11; u
= 5; afrmt
= "%011lo"; break;
1210 frmt
= " %03o"; break;
1219 case 2: a
= 8; s
= 3; n
= 3; m
= 4; u
= 6; afrmt
= "%04X"; break;
1220 case 3: a
= 13; s
= 3; n
= 6; m
= 6; u
= 7; afrmt
= "%06X"; break;
1221 case 4: a
= 13; s
= 3; n
= 4; m
= 8; u
= 7; afrmt
= "%08X"; break;
1223 frmt
= " %02X"; break;
1228 case 2: a
= 10; s
= 4; n
= 4; m
= 5; u
= 4; afrmt
= "%05u"; break;
1229 case 3: a
= 14; s
= 4; n
= 5; m
= 8; u
= 5; afrmt
= "%08u"; break;
1230 case 4: a
= 14; s
= 4; n
= 3; m
= 10; u
= 5; afrmt
= "%010u"; break;
1232 frmt
= " %03u"; break;
1237 case 2: a
= 10; s
= 4; n
= 3; m
= 6; u
= 4; afrmt
= "%06o"; break;
1238 case 3: a
= 14; s
= 4; n
= 5; m
= 8; u
= 5; afrmt
= "%08o"; break;
1239 case 4: a
= 14; s
= 4; n
= 2; m
= 11; u
= 5; afrmt
= "%011o"; break;
1241 frmt
= " %03o"; break;
1250 rp
= &rb
[a
+ (s
* gcntr
)];
1253 * Number must be of proper radix
1255 if (!dgt(r
, rp
, s
-1)) {
1256 fprintf(rfp
, "%s", rb
);
1261 * Output new data value, overwrite relocation codes
1263 sprintf(str
, frmt
, v
);
1264 strncpy(rp
-1, str
, s
);
1269 * Output relocated code address
1272 if (dgt(r
, &rb
[n
], m
)) {
1273 sprintf(str
, afrmt
, cpc
);
1274 strncpy(&rb
[n
], str
, m
);
1278 * Output an error line if required
1281 switch(ASxxxx_VERSION
) {
1283 fprintf(rfp
, "?ASlink-Warning-%s\n", errmsg3
[err
]);
1291 * Fix 'u' if [nn], cycles, is specified
1293 if (rb
[a
+ (s
*u
) - 1] == CYCNT_END
) {
1297 * Output text line when updates finished
1300 fprintf(rfp
, "%s", rb
);