3 # Copyright (c) 2002 Kevin L. Pauba
8 # SDCC is licensed under the GNU Public license (GPL) v2. Note that
9 # this license covers the code to the compiler and other executables,
10 # but explicitly does not cover any code or objects generated by sdcc.
11 # We have not yet decided on a license for the run time libraries, but
12 # it will not put any requirements on code linked against it. See:
14 # http://www.gnu.org/copyleft/gpl.html
16 # See http://sdcc.sourceforge.net/ for the latest information on sdcc.
20 ($junk, $file, $version, $date, $time, $programmer, $status)
21 = split(/\s+/, $rcsid);
22 ($programName) = ($file =~ /(\S+),v/);
24 if ($#ARGV < 0 || $#ARGV > 1 ) {
27 $processor = uc(shift);
30 if ($^O eq 'MSWin32') {
32 if (defined($path = $ENV{'GPUTILS_HEADER_PATH'}) || defined($path = $ENV{'GPUTILS_LKR_PATH'})) {
36 die "Could not find gpasm includes.\n";
42 # Nathan Hurst <njh@mail.csse.monash.edu.au>: find gputils on Debian
44 if ( -x "/usr/share/gputils") {
45 $path = "/usr/share/gputils";
46 } elsif ( -x "/usr/share/gpasm") {
47 $path = "/usr/share/gpasm";
49 die "Could not find gpasm includes.\n";
56 # Read the symbols at the end of this file.
61 if (/^\s*alias\s+(\S+)\s+(\S+)/) {
63 # Set an alias for a special function register.
64 # Some MPASM include files are not entirely consistent
68 } elsif (/^\s*address\s+(\S+)\s+(\S+)/) {
70 # Set a default address for a special function register.
71 # Some MPASM include files don't specify the address
75 foreach $device (split(/[,\s]+/, $devices)) {
76 $addr{"p$device", "$1"} = $2;
78 } elsif (/^\s*bitmask\s+(\S+)\s+/) {
80 # Set the bitmask that will be used in the 'memmap' pragma.
83 foreach $register (split(/\s+/, $')) {
84 $bitmask{"$register"} = $bitmask;
86 } elsif (/^\s*ram\s+(\S+)\s+(\S+)\s+(\S+)/) {
90 foreach $device (split(/[,\s]+/, $devices)) {
91 $ram{"p$device"} .= "#pragma memmap $lo $hi RAM $bitmask$'";
93 } elsif (/^\s*processor\s+/) {
96 } elsif (/^\s*(\S+)/) {
99 foreach $key (split) {
100 eval "\$type{'$key'} = $type;";
103 foreach $key (split) {
104 eval "\$type{'$key'} = $type;";
110 # Read the linker file.
112 # $linkFile = "$path/lkr/" . lc $processor . ".lkr";
113 # open(LINK, "<$linkFile")
114 # || die "$programName: Error: Cannot open linker file $linkFile ($!)\n";
116 # if (/^(\S+)\s+NAME=(\S+)\s+START=(\S+)\s+END=(\S+)\s+(PROTECTED)?/) {
121 # $protected = 1 if ($5 =~ /protected/i);
123 # if ($type =~ /(SHAREBANK)|(DATABANK)/i) {
124 # $ram{"p$processor"} .=
125 # sprintf("#pragma memmap %7s %7s RAM 0x000\t// $name\n",
128 # } elsif (/^SECTION\s+NAME=(\S+)\s+ROM=(\S+)\s+/) {
132 # Create header for pic${processor}.c file
133 $lcproc = "pic" . lc($processor);
135 /* Register definitions for $lcproc.
136 * This file was automatically generated by:
137 * $programName V$version
138 * Copyright (c) 2002, Kevin L. Pauba, All Rights Reserved
140 #include <${lcproc}.h>
147 $defaultType = 'other';
148 $includeFile = $path.$path_delim.'header'.$path_delim.'p'.lc($processor).'.inc';
149 $defsFile = "pic" . lc($processor) . ".c";
150 open(HEADER, "<$includeFile")
151 || die "$programName: Error: Cannot open include file $includeFile ($!)\n";
154 if (/^;-+ (\S+) Bits/i) {
155 # also accept "UIE/UIR Bits"
156 foreach $name (split(/\//, $1)) {
157 if (defined($alias{$name})) {
158 $defaultType = "bits $alias{$name}";
160 $defaultType = "bits $name";
165 } elsif (/^;-+ Register Files/i) {
166 $defaultType = 'sfr';
175 # Convert ASM comments to C style.
178 } elsif (/^\s*IFNDEF __(\S+)/) {
184 } elsif (/^\s*(\S+)\s+EQU\s+H'(.+)'/) {
186 # Useful bit of information.
194 if (defined($type{"p$processor", "$name"})) {
195 $type = $type{"p$processor", "$name"};
196 } elsif (defined($type{"$name"})) {
197 $type = $type{"$name"};
199 $type = $defaultType;
202 if (defined($bitmask{"p$processor", "$name"})) {
203 $bitmask = $bitmask{"p$processor", "$name"};
204 # } elsif (defined($bitmask{"$name"})) {
205 # $bitmask = $bitmask{"$name"};
210 if ($type eq 'sfr') {
212 # A special function register.
214 $pragmas .= sprintf("#pragma memmap %s_ADDR %s_ADDR "
216 $name, $name, $bitmask, $name);
217 if (defined $addr{"p$processor", "$name"}) {
218 $addresses .= sprintf("#define %s_ADDR\t0x%s\n", $name, $addr{"p$processor", "$name"});
220 $addresses .= sprintf("#define %s_ADDR\t0x%s\n", $name, $value);
222 $body .= sprintf("extern __sfr __at %-30s $name;$rest\n", "(${name}_ADDR)" );
223 $c_head .= sprintf("__sfr __at %-30s $name;\n", "(${name}_ADDR)");
224 $addr{"p$processor", "$name"} = "0x$value";
225 } elsif ($type eq 'volatile') {
227 # A location that can change without
228 # direct program manipulation.
230 $pragmas .= sprintf("#pragma memmap %s_ADDR %s_ADDR "
232 $name, $name, $bitmask, $name);
233 $body .= sprintf("extern __data __at %-30s $name;$rest\n", "(${name}_ADDR) volatile char");
234 $c_head .= sprintf("__data __at %-30s $name;\n", "(${name}_ADDR) volatile char");
235 if (defined $addr{"p$processor", "$name"}) {
236 $addresses .= sprintf("#define %s_ADDR\t0x%s\n", $name, $addr{"p$processor", "$name"});
238 $addresses .= sprintf("#define %s_ADDR\t0x%s\n", $name, $value);
240 } elsif ($type =~ /^bits/) {
241 ($junk, $register) = split(/\s/, $type);
243 $addr = $addr{"$register"};
244 # prepare struct declaration
245 for ($k=0; $k < scalar @{$bits{"$register"}->{oct($bit)}}; $k++) {
246 $name = "" if ($bits{"$register"}->{oct($bit)} eq $name)
249 push @{$bits{"$register"}->{oct($bit)}}, $name;
253 # Other registers, bits and/or configurations.
255 if ($type eq 'other') {
259 $body .= sprintf("#define %-20s 0x%s$rest\n", $name, $value);
262 # A symbol that isn't defined in the data
263 # section at the end of the file. Let's
264 # add a comment so that we can add it later.
266 $body .= sprintf("#define %-20s 0x%s$rest\n",
275 } elsif (/__MAXRAM\s+H'([0-9a-fA-F]+)'/) {
276 $maxram .= "//\n// Memory organization.\n//\n";
278 . $ram{"p$processor"} . "\n"
283 # Anything else we'll just comment out.
290 // Register Declarations for Microchip $processor Processor
293 // This header file was automatically generated by:
295 //\t$programName V$version
297 //\tCopyright (c) 2002, Kevin L. Pauba, All Rights Reserved
299 //\tSDCC is licensed under the GNU Public license (GPL) v2. Note that
300 //\tthis license covers the code to the compiler and other executables,
301 //\tbut explicitly does not cover any code or objects generated by sdcc.
302 //\tWe have not yet decided on a license for the run time libraries, but
303 //\tit will not put any requirements on code linked against it. See:
305 //\thttp://www.gnu.org/copyleft/gpl/html
307 //\tSee http://sdcc.sourceforge.net/ for the latest information on sdcc.
310 #ifndef P${processor}_H
311 #define P${processor}_H
314 // Register addresses.
321 // bitfield definitions
326 ## create struct declarations
327 foreach $reg (sort keys %bits)
329 $structs .= "// ----- $reg bits --------------------\n";
330 $structs .= "typedef union {\n";
333 $structs .= " struct {\n";
334 for ($i=0; $i < 8; $i++)
336 @names = @{$bits{$reg}->{oct($i)}};
337 if ($max < scalar @names) { $max = scalar @names; }
338 if ($idx >= scalar @names) {
339 $structs .= " unsigned char :1;\n";
340 } else { # (1 == scalar @names) {
341 $structs .= " unsigned char " . $names[$idx] . ":1;\n";
343 # $structs .= " union {\n";
344 # foreach $name (@names) {
345 # $structs .= " unsigned char " . $name . ":1;\n";
347 # $structs .= " };\n";
352 } while ($idx < $max);
353 $structs .= "} __${reg}_bits_t;\n";
354 $structs .= "extern volatile __${reg}_bits_t __at(${reg}_ADDR) ${reg}_bits;\n\n";
355 $c_head .= "volatile __${reg}_bits_t __at(${reg}_ADDR) ${reg}_bits;\n";
357 # emit defines for individual bits
358 for ($i=0; $i < 8; $i++)
360 @names = @{$bits{$reg}->{oct($i)}};
361 foreach $field (@names) {
362 $structs .= sprintf("#define %-20s ${reg}_bits.$field\n", $field);
375 open(DEFS, ">$defsFile") or die "Could not open $defsFile for writing.";
376 print DEFS $c_head . "\n";
382 inc2h.pl - A utility to convert MPASM include files to header files
383 suitable for the SDCC compiler.
385 License: Copyright (c) 2002 Kevin L. Pauba
387 SDCC is licensed under the GNU Public license (GPL) v2; see
388 http://www.gnu.org/copyleft/gpl.html See http://sdcc.sourceforge.net/
389 for the latest information on sdcc.
391 Usage: $programName processor [path]
395 processor The name of the processor (16f84, 16f877, etc.)
397 path The path to the parent of the "header" and "lkr"
398 directories. The default is "/usr/share/gpasm".
400 The header file will be written to the standard output.
410 # processor <processor_name>
411 # address <register_name> <hex_address>
412 # bitmask <bitmask> <register_list>
413 # ram <lo_address> <hi_address> <bitmask>
414 # sfr <register_list>
415 # volatile <address_list>
419 alias OPTION_REG OPTION