1 /***********************************************************************
2  *
3  *  AVRA - Assembler for the Atmel AVR microcontroller series
4  *
5  *  Copyright (C) 1998-2020 The AVRA Authors
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; see the file COPYING.  If not, write to
19  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  *  Boston, MA 02111-1307, USA.
21  *
22  *
23  *  Authors of AVRA can be reached at:
24  *     email: jonah@omegav.ntnu.no, tobiw@suprafluid.com
25  *     www: https://github.com/Ro5bert/avra
26  */
27 
28 
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "misc.h"
33 #include "avra.h"
34 #include "device.h"
35 
36 #define DEV_VAR    "__DEVICE__"	/* Device var name */
37 #define FLASH_VAR  "__FLASH_SIZE__"	/* Flash size var name */
38 #define EEPROM_VAR "__EEPROM_SIZE__"	/* EEPROM size var name */
39 #define RAM_VAR    "__RAM_SIZE__"	/* RAM size var name */
40 #define DEV_PREFIX "__"		/* Device name prefix */
41 #define DEV_SUFFIX "__"		/* Device name suffix */
42 #define DEF_DEV_NAME "DEFAULT"	/* Default device name (without prefix/suffix) */
43 #define MAX_DEV_NAME 32		/* Max device name length */
44 
45 
46 /* Field Order:
47  * name, flash size (words), RAM start, RAM size (bytes), EEPROM size (bytes),
48  * flags */
49 /* IMPORTANT: THE FLASH SIZE IS IN WORDS, NOT BYTES. This has been a fairly
50  * consistent source of bugs when new devices are added. */
51 struct device device_list[] = {
52 	/* Default device */
53 	{NULL, 4194304, 0x60, 8388608, 65536, 0}, /* Total instructions: 137 */
54 
55 	/* ATtiny Series */
56 	{"ATtiny4"     ,    256, 0x040,    32,    0, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP|DF_AVR8L},
57 	{"ATtiny5"     ,    256, 0x040,    32,    0, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP|DF_AVR8L},
58 	{"ATtiny9"     ,    512, 0x040,    32,    0, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP|DF_AVR8L},
59 	{"ATtiny10"    ,    512, 0x040,    32,    0, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP|DF_AVR8L},
60 	{"ATtiny11"    ,    512, 0x000,     0,    0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
61 	{"ATtiny12"    ,    512, 0x000,     0,   64, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
62 	{"ATtiny13"    ,    512, 0x060,    64,   64, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
63 	{"ATtiny13A"   ,    512, 0x060,    64,   64, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
64 	{"ATtiny15"    ,    512, 0x000,     0,   64, DF_NO_MUL|DF_NO_JMP|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP|DF_TINY1X},
65 	{"ATtiny20"    ,   1024, 0x040,   128,    0, DF_NO_MUL|DF_NO_JMP|DF_NO_EIJMP|DF_NO_EICALL|DF_NO_MOVW|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK|DF_AVR8L},
66 	{"ATtiny22"    ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
67 	{"ATtiny24"    ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
68 	{"ATtiny24A"   ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
69 	{"ATtiny25"    ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
70 	{"ATtiny26"    ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
71 	{"ATtiny28"    ,   1024, 0x000,     0,    0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
72 	{"ATtiny44"    ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
73 	{"ATtiny44A"   ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
74 	{"ATtiny45"    ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
75 	{"ATtiny48"    ,   2048, 0x100,   256,   64, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
76 	{"ATtiny84"    ,   4096, 0x060,   512,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
77 	{"ATtiny85"    ,   4096, 0x060,   512,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
78 	{"ATtiny88"    ,   4096, 0x100,   512,   64, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
79 	{"ATtiny261A"  ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
80 	{"ATtiny461A"  ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
81 	{"ATtiny861A"  ,   4096, 0x060,   512,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
82 	{"ATtiny2313"  ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
83 	{"ATtiny2313A" ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
84 	{"ATtiny4313"  ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_ELPM|DF_NO_ESPM|DF_NO_EICALL|DF_NO_EIJMP},
85 
86 	/* AT90 series */
87 	{"AT90S1200"   ,    512, 0x000,     0,   64, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
88 	{"AT90S2313"   ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
89 	{"AT90S2323"   ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
90 	{"AT90S2333"   ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
91 	{"AT90S2343"   ,   1024, 0x060,   128,  128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
92 	{"AT90S4414"   ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
93 	{"AT90S4433"   ,   2048, 0x060,   128,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
94 	{"AT90S4434"   ,   2048, 0x060,   256,  256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
95 	{"AT90S8515"   ,   4096, 0x060,   512,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
96 	{"AT90C8534"   ,   4096, 0x060,   256,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
97 	{"AT90S8535"   ,   4096, 0x060,   512,  512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
98 
99 	/* AT90USB series */
100 	/* AT90USB168 */
101 	/* AT90USB1287 */
102 
103 	/* ATmega series */
104 	{"ATmega8"     ,   4096, 0x060,  1024,  512, DF_NO_JMP|DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
105 	{"ATmega8A"    ,   4096, 0x060,  1024,  512, DF_NO_JMP|DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
106 	{"ATmega161"   ,   8192, 0x060,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
107 	{"ATmega162"   ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
108 	{"ATmega163"   ,   8192, 0x060,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
109 	{"ATmega16"    ,   8192, 0x060,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
110 	{"ATmega323"   ,  16384, 0x060,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
111 	{"ATmega32"    ,  16384, 0x060,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
112 	{"ATmega603"   ,  32768, 0x060,  4096, 2048, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_MUL|DF_NO_MOVW|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK},
113 	{"ATmega103"   ,  65536, 0x060,  4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_MUL|DF_NO_MOVW|DF_NO_LPM_X|DF_NO_ELPM_X|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK},
114 	{"ATmega104"   ,  65536, 0x060,  4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM}, /* Old name for mega128 */
115 	{"ATmega128"   ,  65536, 0x100,  4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM},
116 	{"ATmega128A"  ,  65536, 0x100,  4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM},
117 	{"ATmega48"    ,   2048, 0x100,   512,  256, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
118 	{"ATmega48A"   ,   2048, 0x100,   512,  256, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
119 	{"ATmega48P"   ,   2048, 0x100,   512,  256, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
120 	{"ATmega48PA"  ,   2048, 0x100,   512,  256, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
121 	{"ATmega88"    ,   4096, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
122 	{"ATmega88A"   ,   4096, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
123 	{"ATmega88P"   ,   4096, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
124 	{"ATmega88PA"  ,   4096, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
125 	{"ATmega168"   ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
126 	{"ATmega168A"  ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
127 	{"ATmega168P"  ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
128 	{"ATmega168PA" ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
129 	{"ATmega328"   ,  16384, 0x100,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
130 	{"ATmega328P"  ,  16384, 0x100,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
131 	{"ATmega328PB" ,  16384, 0x100,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
132 	{"ATmega8515"  ,   8192, 0x060,   512,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
133 	{"ATmega1280"  ,  65536, 0x200,  8192, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM},
134 	{"ATmega164P"  ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
135 	{"ATmega164PA" ,   8192, 0x100,  1024,  512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
136 	{"ATmega324P"  ,  16384, 0x100,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
137 	{"ATmega324PA" ,  16384, 0x100,  2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
138 	{"ATmega644"   ,  32768, 0x100,  4096, 2048, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
139  	{"ATmega644P"  ,  32768, 0x100,  4096, 2096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
140 	{"ATmega644PA" ,  32768, 0x100,  4096, 2096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM},
141 	{"ATmega1284P" ,  65536, 0x100, 16384, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM},
142 	{"ATmega1284PA",  65536, 0x100, 16384, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM},
143 	{"ATmega2560"  , 131072, 0x200,  8192, 4096, DF_NO_ESPM},
144 
145 	/* Other */
146 	{"AT94K"       ,   8192, 0x060, 16384,    0, DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
147 
148 	{NULL, 0, 0, 0, 0}
149 };
150 
151 static int LastDevice=0;
152 
153 /* Define vars for device in LastDevice. */
154 static void
def_dev(struct prog_info * pi)155 def_dev(struct prog_info *pi)
156 {
157 	def_var(pi,DEV_VAR,LastDevice);
158 	def_var(pi,FLASH_VAR,device_list[LastDevice].flash_size);
159 	def_var(pi,EEPROM_VAR,device_list[LastDevice].eeprom_size);
160 	def_var(pi,RAM_VAR,device_list[LastDevice].ram_size);
161 }
162 
get_device(struct prog_info * pi,char * name)163 struct device *get_device(struct prog_info *pi, char *name)
164 {
165 	int i = 1;
166 
167 	LastDevice = 0;
168 	if (name == NULL) {
169 		def_dev(pi);
170 		return (&device_list[0]);
171 	}
172 	while (device_list[i].name) {
173 		if (!nocase_strcmp(name, device_list[i].name)) {
174 			LastDevice=i;
175 			def_dev(pi);
176 			return (&device_list[i]);
177 		}
178 		i++;
179 	}
180 	def_dev(pi);
181 	return (NULL);
182 }
183 
184 /* Pre-define devices. */
185 int
predef_dev(struct prog_info * pi)186 predef_dev(struct prog_info *pi)
187 {
188 	int i;
189 	char temp[MAX_DEV_NAME+1];
190 	def_dev(pi);
191 	for (i=0; (!i)||(device_list[i].name); i++) {
192 		strncpy(temp,DEV_PREFIX,MAX_DEV_NAME);
193 		if (!i) strncat(temp,DEF_DEV_NAME,MAX_DEV_NAME);
194 		else strncat(temp,device_list[i].name,MAX_DEV_NAME);
195 		strncat(temp,DEV_SUFFIX,MAX_DEV_NAME);
196 		/* Forward references allowed. But check, if everything is ok ... */
197 		if (pi->pass==PASS_1) { /* Pass 1 */
198 			if (test_constant(pi,temp,NULL)!=NULL) {
199 				fprintf(stderr,"Error: Can't define symbol %s twice. Please don't use predefined symbols !\n", temp);
200 				return (False);
201 			}
202 			if (def_const(pi, temp, i)==False)
203 				return (False);
204 		} else { /* Pass 2 */
205 			int j;
206 			if (get_constant(pi, temp, &j)==False) {  /* Defined in Pass 1 and now missing ? */
207 				fprintf(stderr,"Constant %s is missing in pass 2\n",temp);
208 				return (False);
209 			}
210 			if (i != j) {
211 				fprintf(stderr,"Constant %s changed value from %d in pass1 to %d in pass 2\n",temp,j,i);
212 				return (False);
213 			}
214 			/* OK. definition is unchanged */
215 		}
216 	}
217 	return (True);
218 }
219 
220 void
list_devices(void)221 list_devices(void)
222 {
223 	int i = 1;
224 	printf("Device name   | Flash size | RAM start | RAM size | EEPROM size |  Supported\n"
225 	       "              |  (words)   | (bytes)   | (bytes)  |   (bytes)   | instructions\n"
226 	       "--------------+------------+-----------+----------+-------------+--------------\n"
227 	       " (default)    |    %7ld |    0x%04lx |  %7ld |       %5ld |          %3d\n",
228 	       device_list[0].flash_size,
229 	       device_list[0].ram_start,
230 	       device_list[0].ram_size,
231 	       device_list[0].eeprom_size,
232 	       count_supported_instructions(device_list[0].flag));
233 	while (device_list[i].name) {
234 		printf(" %-12s |    %7ld |    0x%04lx |  %7ld |       %5ld |          %3d\n",
235 		       device_list[i].name,
236 		       device_list[i].flash_size,
237 		       device_list[i].ram_start,
238 		       device_list[i].ram_size,
239 		       device_list[i].eeprom_size,
240 		       count_supported_instructions(device_list[i].flag));
241 		i++;
242 	}
243 }
244 
245 /* end of device.c */
246 
247