1#!/usr/bin/perl -w
2
3=back
4
5  Copyright (C) 2012-2015, Molnar Karoly <molnarkaroly@users.sf.net>
6
7    This file is part of SDCC.
8
9    This software is provided 'as-is', without any express or implied
10    warranty.  In no event will the authors be held liable for any damages
11    arising from the use of this software.
12
13    Permission is granted to anyone to use this software for any purpose,
14    including commercial applications, and to alter it and redistribute it
15    freely, subject to the following restrictions:
16
17    1. The origin of this software must not be misrepresented; you must not
18       claim that you wrote the original software. If you use this software
19       in a product, an acknowledgment in the product documentation would be
20       appreciated but is not required.
21
22    2. Altered source versions must be plainly marked as such, and must not be
23       misrepresented as being the original software.
24
25    3. This notice may not be removed or altered from any source distribution.
26
27================================================================================
28
29  cinc2h.pl (common-inc2h.pl)
30
31  This program parse the gpasm header (p1xxx.inc) files and creates
32  from them the SDCC header and device library files. In addition it
33  needs the gpprocessor.c file also. These is included in the source
34  package of gputils. Mode of download of the latest source:
35
36        http://gputils.sourceforge.net/#Download
37
38  The program is available on request provide assistance: cinc2h.pl -h
39
40  -------------------------------------------------
41
42  Steps to add a new target device to SDCC/PIC16:
43  (Following Raphael Neider <rneider AT web.de>)
44
45   1. Create the picDEVICE.c and picDEVICE.h from pDEVICE.inc using
46      ./cinc2h.pl -p 18f4520 -cb -cp -gp "path/to/gputils_source" -o "path/to/output"
47
48   2. mv picDEVICE.h $SDCC/device/non-free/include/pic16
49   3. mv picDEVICE.c $SDCC/device/non-free/lib/pic16/libdev
50   4. either
51
52      (a) adjust $SDCC/device/lib/pic16/libio/*.ignore
53          if the device does not support ADC, I2C, or USART
54          --- OR ---
55      (b) adjust
56          * SDCC/scripts/pic18fam-h-gen.pl
57          * SDCC/device/include/pic16/adc.h (if required)
58          * SDCC/device/include/pic16/usart.h (if required)
59          * SDCC/device/lib/pic16/libio/*/* (if required)
60          to add the new device to the appropriate I/O style
61          and implement new styles (if required).
62
63          Having modified pic18fam-h-gen.pl, you need to run the
64          script to generate pic18fam.h.gen, which in turn must
65          then replace your .../include/pic16/pic18fam.h to take
66          effect; see pic18fam-h-gen.pl for usage information.
67   6. edit $SDCC/device/include/pic16/pic18fregs.h
68   7. edit $SDCC/device/include/pic16/pic16devices.txt
69   8. run cd $SDCC/device/non-free/lib/pic16 && sh update.sh
70      to regenerate .../libdev/Makefile.am and processors.ac
71
72   The file format of steps 6 and 7 is self explanatory, in most
73   if not all cases you can copy and paste another device's records
74   and adjust them to the newly added device.
75
76  -------------------------------------------------
77
78  Steps to add a new target device to SDCC/PIC14:
79
80   1. Create the picDEVICE.c and picDEVICE.h from pDEVICE.inc using
81      ./cinc2h.pl -p 16f1503 -cb -cp -gp "path/to/gputils_source" -o "path/to/output"
82
83   2. mv picDEVICE.h $SDCC/device/non-free/include/pic14
84   3. mv picDEVICE.c $SDCC/device/non-free/lib/pic14/libdev
85   4. add DEVICE to $SDCC/device/non-free/lib/pic14/libdev/devices.txt
86      (The names of the enhanced devices the "# enhanced cores" line
87       after follow.)
88
89   5. edit $SDCC/device/include/pic14/pic14devices.txt
90
91   The file format of step 5 is self explanatory, in most if not all
92   cases you can copy and paste another device's records and adjust
93   them to the newly added device.
94
95  $Id: cinc2h.pl 9450 2016-01-09 16:47:43Z molnarkaroly $
96=cut
97
98use strict;
99use warnings;
100no if $] >= 5.018, warnings => "experimental::smartmatch";        # perl 5.16
101use 5.12.0;                     # when (regex)
102use File::Path 'make_path';
103use feature 'switch';           # Starting from 5.10.1.
104use POSIX qw(strftime);
105
106use constant FALSE => 0;
107use constant TRUE  => 1;
108
109use constant ST_NONE       => 0;
110use constant ST_REG_ADDR   => 1;
111use constant ST_REG1_DEF   => 2;
112use constant ST_REG2_DEF   => 3;
113use constant ST_RAM_DEF    => 4;
114use constant ST_CONFIG_DEF => 5;
115use constant ST_DEVID_DEF  => 6;
116use constant ST_IDLOC_DEF  => 7;
117
118use constant DIST_ADDRSIZE => 32;
119use constant DIST_BITSIZE  => 32;
120use constant DIST_DEFSIZE  => 32;
121use constant DIST_COMSIZE  => 32;
122
123my $PROGRAM  = 'cinc2h.pl';
124my $time_str = '';
125my $year     = '';
126
127my $gputils_path   = "$ENV{HOME}/svn_snapshots/gputils/gputils";
128my $gp_header_path = '';
129my $gpprocessor_c  = 'gpprocessor.c';
130my $gpproc_path;
131
132my $name_filter = qr/10l?f\d+[a-z]*|1[26]((c(e|r)?)|hv)\d+[a-z]*|1[268]l?f\d+([a-z]*|[a-z]+\d+[a-z]*)/;
133my $header_name_filter = 'p${name_filter}.inc';
134
135my $p14_out_path = 'pic14';
136my $p16_out_path = 'pic16';
137
138my $mcu;
139my $short_mcu_name;
140my $is_pic16   = FALSE;
141my $conf_size  = 4;
142my $caddr_size = 4;
143my $conf_head  = '_';
144my $verbose    = 0;
145
146my $create_bitfields  = FALSE;
147my $emit_legacy_names = FALSE;
148my $no_timestamp      = FALSE;
149
150my $section = '//' . ('=' x 78);
151my $btail = 'bits';
152my $btype_t = "${btail}_t";
153
154        # Here those names to be entered that are defective.
155        # BAD => 'GOOD'  or
156        # 'BAD' => 'GOOD'
157
158my %correction_of_names =
159  (
160  OPTION => 'OPTION_REG'
161  );
162
163        # At some processors there is such register name, that is different
164        # from what the other processors in used. This is a replacement table.
165
166my %register_aliases =
167  (
168  BAUDCTL => 'BAUDCON'
169  );
170
171#-----------------------------------------------
172
173=back
174        The structure of one element of the @registers array:
175
176        {
177        NAME        => '',      The name of register.
178        ADDRESS     => 0,       The address of register.
179        NEED_PREFIX => 0,       Indicates if in front the name of bits necessary an prefix.
180        BITNAMES    => [        The bits of register.
181                         [],      The names of 0th bit.
182                         [],
183                         [],
184                         [],
185                         [],
186                         [],
187                         [],
188                         []       The names of 7th bit.
189                       ],
190
191                       ...
192
193                       []
194
195        BITFIELDS   => {
196                       'ADCS' => {           This the descriptor of the ADCS field.
197                                 ADDRESSES => [],  Physical start addresses of bits of the field.
198                                 INDEXES   => [],  Bit indexes of bits of the field (ADCS2 -> '2').
199                                 WIDTH     => 0    So many bit the width of the bit-field.
200                                 },
201
202                       'ANS'  => {}
203
204                       ...
205
206                       }
207        }
208=cut
209
210my @registers = ();
211
212#-----------------------------------------------
213
214        # References of registers according to name of registers.
215my %reg_refs_by_names = ();
216
217        # References of registers according to name of bits of registers.
218        # With help of recognizable the repetitive bit names.
219my %reg_refs_by_bits = ();
220
221#-----------------------------------------------
222
223=back
224        The structure of one element of the @configs array:
225
226        {
227        NAME    => '',      The name of config.
228        ADDRESS => 0,       The address of config.
229        OPTIONS => [        The options of config.
230                     {
231                     NAME        => '',
232                     VALUE       => 0,
233                     EXPLANATION => ''
234                     },
235
236                     ...
237
238                     {
239                     }
240                   ]
241        }
242=cut
243
244my @configs = ();
245
246#-----------------------------------------------
247
248my %conf_names = ();
249
250my @devids = ();
251my @idlocs = ();
252
253my $header_name;
254my $device_name;
255my $out_path = './';
256my $out_handler;
257
258my $device_registers = '';
259my $full_bitdefs     = '';
260my $legacy_names     = '';
261
262################################################################################
263################################################################################
264################################################################################
265################################################################################
266
267sub basename($)
268  {
269  return ($_[0] =~ /([^\/]+)$/) ? $1 : '';
270  }
271
272#-------------------------------------------------------------------------------
273
274sub param_exist($$)
275  {
276  die "This option \"$_[0]\" requires a parameter.\n" if ($_[1] > $#ARGV);
277  }
278
279#-------------------------------------------------------------------------------
280
281sub str2int($)
282  {
283  my $Str = $_[0];
284
285  return hex($1)   if ($Str =~ /^H'([[:xdigit:]]+)'$/io);
286  return hex($1)   if ($Str =~ /^0x([[:xdigit:]]+)$/io);
287  return int($Str) if ($Str =~ /^-?\d+$/o);
288
289  die "str2int(): This string not integer: \"$Str\"";
290  }
291
292#-------------------------------------------------------------------------------
293
294sub align($$)
295  {
296  my $text = $_[0];
297  my $al   = $_[1] - length($text);
298
299        # One space will surely becomes behind it.
300  $al = 1 if ($al < 1);
301
302  return ($text . ' ' x $al);
303  }
304
305#-------------------------------------------------------------------------------
306
307sub Log
308  {
309  return if (pop(@_) > $verbose);
310  foreach (@_) { print $_; }
311  print "\n";
312  }
313
314#-------------------------------------------------------------------------------
315
316sub Out
317  {
318  foreach (@_) { print $out_handler $_; }
319  }
320
321#-------------------------------------------------------------------------------
322
323sub Outl
324  {
325  Out(@_);
326  print $out_handler "\n";
327  }
328
329#-------------------------------------------------------------------------------
330
331sub versionCompare($$)
332  {
333  my ($Str1, $Str2) = @_;
334
335  if ((${$Str1} =~ /^\d/o) && (${$Str2} =~ /^\d/o))
336    {
337        # $Str1 number and $Str2 number
338    return (int(${$Str1}) <=> int(${$Str2}));
339    }
340
341  return (${$Str1} cmp ${$Str2});
342  }
343
344#-------------------------------------------------------------------------------
345
346sub versionSort($$)
347  {
348  my @a_s = ($_[0] =~ /(\d+|\D+)/go);
349  my @b_s = ($_[1] =~ /(\d+|\D+)/go);
350  my ($i, $k, $end, $ret);
351
352  $i = scalar(@a_s);
353  $k = scalar(@b_s);
354
355  if ($i < $k)
356    {
357    $end = $i;
358    $ret = -1;
359    }
360  elsif ($i == $k)
361    {
362    $end = $i;
363    $ret = 0;
364    }
365  else
366    {
367    $end = $k;
368    $ret = 1;
369    }
370
371  for ($i = 0; $i < $end; ++$i)
372    {
373    $k = versionCompare(\$a_s[$i], \$b_s[$i]);
374
375    return $k if ($k != 0);
376    }
377
378  return $ret;
379  }
380
381#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
382# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
383#@@@@@@@@@@@@@                                                      @@@@@@@@@@@@
384#@@@@@@@@@@@@  Load all definitions, which will find in the header.  @@@@@@@@@@@
385#@@@@@@@@@@@@@                                                      @@@@@@@@@@@@
386# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
387#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
388
389        # If the $Word included in a list then it will replace.
390
391sub correct_name($)
392  {
393  my $Word = $_[0];
394  my $corr = $correction_of_names{$Word};
395
396  if (defined($corr))
397    {
398    Log("$Word --> $corr ($mcu)", 7);
399    return $corr;
400    }
401
402  return $Word;
403  }
404
405#-------------------------------------------------------------------------------
406
407        # Adds to the list the $Name register.
408
409sub new_register($$)
410  {
411  my ($Name, $Address) = @_;
412
413  if (defined($reg_refs_by_names{$Name}))
414    {
415    die "The \"$Name\" register has been included on the list. ($mcu)\n";
416    }
417
418  my $reg = {
419            NAME        => correct_name($Name),
420            ADDRESS     => $Address,
421            NEED_PREFIX => FALSE,
422            BITNAMES    => undef,
423            BITFIELDS   => undef
424            };
425
426  push(@registers, $reg);
427  $reg_refs_by_names{$Name} = $reg;
428  return $reg;
429  }
430
431#-------------------------------------------------------------------------------
432
433        # Cuts the unnecessary prefix or suffix.
434
435sub bit_filtration($$)
436  {
437  my ($Regname, $Bits) = @_;
438
439  for (my $i = 0; $i < 8; ++$i)
440    {
441    my $array = $Bits->[$i];
442
443    next if (! defined($array));
444
445    my $changed = 0;
446    my $new_bits = [];
447
448    foreach (@{$array})
449      {
450        # $Regname : 'CMCON'
451        # $_       : 'C1OUT_CMCON'
452        # Operation: 'C1OUT_CMCON' --> 'C1OUT'
453        #
454
455      $changed += ($_ =~ s/^${Regname}_|_${Regname}$//);
456      $changed += ($_ =~ s/^(\d+)$/bit_$1/o);
457      push(@{$new_bits}, $_);
458      }
459
460    $Bits->[$i] = $new_bits if ($changed);
461    }
462  }
463
464#-------------------------------------------------------------------------------
465
466        # Tries the $Bit insert into a bitfield of the $Register.
467
468sub bitfield_preparation($$$)
469  {
470  my ($Register, $Bit, $Address) = @_;
471  my $fields = $Register->{BITFIELDS};
472
473  $fields = $Register->{BITFIELDS} = {} if (! defined($fields));
474
475  Log("BIT: $Bit", 7);
476
477  if ($Bit =~ /(\d+)$/op)
478    {
479    my $flname = ${^PREMATCH};
480    my $flidx  = $1;
481
482    if (! defined($fields->{$flname}))
483      {
484        # Creates a new field.
485
486      Log("BIT first    : $flname\[$Address\] = '$flidx'", 7);
487      $fields->{$flname} = {
488                           ADDRESSES => [ $Address ],
489                           INDEXES   => [],
490                           WIDTH     => 0
491                           };
492      }
493    else
494      {
495        # The bit inserts into an existing field.
496
497      Log("BIT remaining: $flname\[$Address\] = '$flidx'", 7);
498      push(@{$fields->{$flname}->{ADDRESSES}}, $Address);
499      }
500
501    $fields->{$flname}->{INDEXES}->[$Address] = $flidx;
502    }
503  }
504
505#-------------------------------------------------------------------------------
506
507        # If can, classifies the $Bits into a field.
508
509sub bitfield_registration($$)
510  {
511  my ($Register, $Bits) = @_;
512
513  for (my $i = 0; $i < 8; ++$i)
514    {
515    my $array = $Bits->[$i];
516
517    next if (! defined($array));
518
519    Log("bitfield_registration() -- $i", 8);
520    foreach (@{$array})
521      {
522      bitfield_preparation($Register, $_, $i);
523      }
524    }
525  }
526
527#-------------------------------------------------------------------------------
528
529        # In the $Queue are in register's names.
530        # Assigns to these the contents of $Bits.
531
532sub add_reg_bits($$)
533  {
534  my ($Queue, $Bits) = @_;
535
536  return if ((scalar(@{$Queue}) == 0) || (scalar(@{$Bits}) == 0));
537
538  foreach (@{$Queue})
539    {
540    next if ($_ eq 'and');      # This here easiest to filter out.
541
542    my $name = correct_name($_);
543    my $reg = $reg_refs_by_names{$name};
544
545    if (! defined($reg))
546      {
547      Log("The $name register is not directly be reached or does not exist. ($mcu)", 2);
548      $reg = new_register($name, -1);
549      }
550
551    bit_filtration($name, $Bits);
552    bitfield_registration($reg, $Bits);
553    $reg->{BITNAMES} = [ @{$Bits} ];
554    }
555
556  @{$Queue} = ();
557  @{$Bits}  = ();
558  }
559
560#-------------------------------------------------------------------------------
561
562        # Finds the $Name in the $Bits.
563
564sub find_bit($$)
565  {
566  my ($Bits, $Name) = @_;
567
568  return FALSE if (! defined($Bits));
569
570  for (my $i = 0; $i < 8; ++$i)
571    {
572    my $array = $Bits->[$i];
573
574    next if (! defined($array));
575
576    foreach (@{$array})
577      {
578      return TRUE if ($_ eq $Name);
579      }
580    }
581
582  return FALSE;
583  }
584
585#-------------------------------------------------------------------------------
586
587        # Adds to the list the $Name config byte/word.
588
589sub add_conf_word($$)
590  {
591  my ($Name, $Address) = @_;
592
593  my $conf = $conf_names{$Name};
594
595  if (defined($conf))
596    {
597        # The $Name config byte/word still unknown, but there are related words.
598
599        # If the $Name config byte/word are defined later than
600        # the associated bits, then this section is executed.
601        #
602
603    $conf->{ADDRESS} = $Address if ($conf->{ADDRESS} < 0 && $Address >= 0);
604    }
605  else
606    {
607        # The $Name config byte/word still unknown and there are no related words.
608
609    $conf = {
610            NAME    => $Name,
611            ADDRESS => $Address,
612            OPTIONS => []
613            };
614
615    push(@configs, $conf);
616    $conf_names{$Name} = $conf;
617    }
618  }
619
620#-------------------------------------------------------------------------------
621
622sub add_conf_options($$)
623  {
624  my ($Queue, $Options) = @_;
625
626  return if ((scalar(@{$Queue}) == 0) || (scalar(@{$Options}) == 0));
627
628  foreach (@{$Queue})
629    {
630    my $conf = $conf_names{$_};
631
632    die "This config unknown: \"$_\" ($mcu)\n" if (! defined($conf));
633
634    $conf->{OPTIONS} = [ @{$Options} ];
635    }
636
637  @{$Queue}   = ();
638  @{$Options} = ();
639  }
640
641#-------------------------------------------------------------------------------
642
643        # Reads the entire content of the $File.
644
645sub read_content_from_header($)
646  {
647  my $File = $_[0];
648  my ($state, $name, $addr);
649  my @queue;
650  my @array;
651
652  open(IN, '<', $File) || die "Can not open the $File header file!\n";
653
654  $state = ST_NONE;
655  @queue = ();
656  @array = ();
657
658  foreach (grep(! /^\s*$/o, <IN>))
659    {
660    chomp;
661    s/\r$//o;
662    s/^\s*|\s*$//go;
663
664    my $line = $_;
665
666    Log("#### \"$line\"", 8);
667
668    given ($state)
669      {
670      when (ST_NONE)
671        {
672        Log(":::: ST_NONE ($line) ($mcu)", 4);
673
674        $state = ST_REG_ADDR if ($line =~ /^;-+\s*Register\s+Files\s*-+$/io);
675        }
676
677     when (ST_REG_ADDR)
678        {
679        Log(":::: ST_REG_ADDR ($line) ($mcu)", 4);
680
681        if ($line =~ /^;-+\s*(.+)Bits\s*-+$/io)
682          {
683        # ;----- STKPTR Bits --------------------------------------------------------
684        # ;----- UIR/UIE Bits -------------------------------------------------------
685        # ;----- TXSTA, TXSTA1 and TXSTA2 Bits --------------------------------------
686        #
687
688        # Therefore need the queue because more register names can be on one line.
689
690          @queue = ($1 =~ /([^\s,\/]+)/go);
691          $state = ST_REG1_DEF;
692          }
693        elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io)  #'
694          {
695        # PORTC     EQU  H'0007'
696        #
697
698          new_register($1, str2int($2));
699          }
700        } # when (ST_REG_ADDR)
701
702      when (ST_REG1_DEF)
703        {
704        Log(":::: ST_REG1_DEF ($line) ($mcu)", 4);
705
706        if ($line =~ /^;\s*I\/O\s+Pin\s+Name\s+Definitions?$/io)
707          {
708        # ;       I/O Pin Name Definitions
709        #
710
711          Log("1 +++ add_reg_bits()", 6);
712          add_reg_bits(\@queue, \@array);
713          $state = ST_REG2_DEF;
714          }
715        elsif ($line =~ /^;\s*RAM\s+Definitions?$/io)
716          {
717        # ;       RAM Definition
718        # ;       RAM Definitions
719        #
720
721          Log("2 +++ add_reg_bits()", 6);
722          add_reg_bits(\@queue, \@array);
723          $state = ST_RAM_DEF;
724          }
725        elsif ($line =~ /^;-+\s*(.+)Bits\s*-+$/io)
726          {
727          my $name = $1;
728
729          Log("3 +++ add_reg_bits()", 6);
730          add_reg_bits(\@queue, \@array);
731
732        # Therefore need the queue because more register names can be on one line.
733
734          @queue = ($name =~ /([^\s,\/]+)/go);
735          }
736        elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io)  #'
737          {
738        # VR2       EQU  H'0002'
739        #
740
741          push(@{$array[str2int($2)]}, $1);
742          }
743        } # when (ST_REG1_DEF)
744
745      when (ST_REG2_DEF)
746        {
747        Log(":::: ST_REG2_DEF ($line) ($mcu)", 4);
748
749        if ($line =~ /^;\s*RAM\s+Definitions?$/io)
750          {
751        # ;       RAM Definition
752        # ;       RAM Definitions
753        #
754
755          Log("4 +++ add_reg_bits()", 6);
756          add_reg_bits(\@queue, \@array);
757          $state = ST_RAM_DEF;
758          }
759        elsif ($line =~ /^;-+\s*([^-]+)\s*-+$/io)
760          {
761          my $name = $1;
762
763          Log("5 +++ add_reg_bits()", 6);
764          add_reg_bits(\@queue, \@array);
765
766        # Therefore need the queue because more register names can be on one line.
767
768          @queue = ($name =~ /([^\s,\/]+)/go);
769          }
770        elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io)  #'
771          {
772        # RE3      EQU  3
773        #
774
775          push(@{$array[int($2)]}, $1);
776          }
777        } # when (ST_REG2_DEF)
778
779      when (ST_RAM_DEF)
780        {
781        Log(":::: ST_RAM_DEF ($line) ($mcu)", 4);
782
783        $state = ST_CONFIG_DEF if ($line =~ /^;\s*Configuration\s+Bits$/io);
784        }
785
786      when (ST_CONFIG_DEF)
787        {
788        Log(":::: ST_CONFIG_DEF ($line) ($mcu)", 4);
789
790        if ($line =~ /^_(DEVID\d*)\s+EQU\s+([\w']+)$/io)  #'
791          {
792          add_conf_options(\@queue, \@array);
793
794          Log("DEVID: $line", 6);
795          push(@devids, { NAME => $1, ADDRESS => str2int($2) });
796          $state = ST_DEVID_DEF;
797          }
798        elsif ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io)  #'
799          {
800          add_conf_options(\@queue, \@array);
801
802          Log("IDLOC: $line", 6);
803          push(@idlocs, { NAME => $1, ADDRESS => str2int($2) });
804          $state = ST_IDLOC_DEF;
805          }
806        elsif ($line =~ /^_(CONFIG\d*\w*)\s+EQU\s+([\w']+)$/io)  #'
807          {
808          Log("CONFIG: $line", 6);
809          add_conf_word(uc($1), str2int($2));
810          }
811        elsif ($line =~ /^;\s*-+\s*(Config\d*\w*)\s+Options\s*-+$/io)
812          {
813          my $name = uc($1);
814
815          Log("1. Config: $line", 6);
816          add_conf_options(\@queue, \@array);
817          add_conf_word($name, -1);
818          push(@queue, $name);
819          }
820        elsif ($line =~ /^;\s*-+\s*Config\s+Word(\d+)\s+Options\s*-+$/io ||
821               $line =~ /^;\s*Configuration\s+Byte\s+(\d+[HL])\s+Options$/io)
822          {
823          my $name = "CONFIG$1";
824
825          Log("2. Config: $line", 6);
826          add_conf_options(\@queue, \@array);
827          add_conf_word($name, 0);
828          push(@queue, $name);
829          }
830        elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)(.+)?$/io)  #'
831          {
832          my ($name, $value) = ($1, str2int($2));
833          my $expl = '';
834
835          if (defined($3))
836            {
837            $expl = $3;
838            $expl =~ s/\s*;\s*//;
839            }
840
841          Log("Config option: $line", 6);
842          push(@array, { NAME => $name, VALUE => $value, EXPLANATION => $expl });
843          }
844        } # when (ST_CONFIG_DEF)
845
846      when (ST_DEVID_DEF)
847        {
848        Log(":::: ST_DEVID_DEF ($line) ($mcu)", 4);
849
850        if ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io)  #'
851          {
852          Log("IDLOC: $line", 6);
853          push(@idlocs, { NAME => $1, ADDRESS => str2int($2) });
854          $state = ST_IDLOC_DEF;
855          }
856        elsif ($line =~ /^_(DEVID\d*)\s+EQU\s+([\w']+)$/io)  #'
857          {
858          Log("DEVID: $line", 6);
859          push(@devids, { NAME => $1, ADDRESS => str2int($2) });
860          }
861        }
862
863      when (ST_IDLOC_DEF)
864        {
865        Log(":::: ST_IDLOC_DEF ($line) ($mcu)", 4);
866
867        if ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io)  #'
868          {
869          Log("IDLOC: $line", 6);
870          push(@idlocs, { NAME => $1, ADDRESS => str2int($2) });
871          }
872        }
873      } # given ($state)
874    } # foreach (grep(! /^\s*$/o, <IN>))
875
876  add_conf_options(\@queue, \@array);
877
878  close(IN);
879
880  return if (! scalar(@registers));
881
882        # Within the array sorts by address the registers.
883
884  @registers = sort {$a->{ADDRESS} <=> $b->{ADDRESS}} @registers;
885  }
886
887#-------------------------------------------------------------------------------
888
889        # Reads the bounds of config area from the gpprocesor.c file.
890
891sub extract_config_area($$)
892  {
893  my ($Conf_start, $Conf_end) = @_;
894
895  open(LIB, '<', $gpproc_path) || die "extract_config_area(): Can not open. -> \"$gpproc_path\"\n";
896
897        # static struct px pics[] = {
898        #   { PROC_CLASS_PIC12E   , "__12F529T39A"  , { "pic12f529t39a"  , "p12f529t39a"    , "12f529t39a"      }, 0xE529,  3,    8, 0x00E0, { 0x07, 0x0F }, 0x06F, {     -1,     -1 }, 0x00FF, 0x0005FF, 0x000600, {       -1,       -1 }, { 0x000640, 0x000643 }, { 0x000FFF, 0x000FFF }, { 0x000600, 0x00063F }, 0x0FF0, "p12f529t39a.inc"  , "12f529t39a_g.lkr"  , 0 },
899        #   { PROC_CLASS_PIC14E   , "__16LF1517"    , { "pic16lf1517"    , "p16lf1517"      , "16lf1517"        }, 0xA517,  4,   32, 0x0F80, { 0x70, 0x7F },    -1, { 0x2000, 0x21EF }, 0x0FFF, 0x001FFF, 0x002000, {       -1,       -1 }, { 0x008000, 0x008003 }, { 0x008007, 0x008008 }, {       -1,       -1 }, 0x3F80, "p16lf1517.inc"    , "16lf1517_g.lkr"    , 0 },
900
901  my $in_table = FALSE;
902
903  while (<LIB>)
904    {
905    chomp;
906
907    if (! $in_table)
908      {
909      $in_table = TRUE if (/^\s*static\s+struct\s+px\s+pics\[\s*\]\s*=\s*\{\s*$/io);
910      }
911    elsif (/\{\s*PROC_CLASS_\w+\s*,\s*"\w+"\s*,\s*\{\s*"\w+"\s*,\s*"\w+"\s*,\s*"(\w+)"\s*}\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\S+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\S+\s*,\s*\S+\s*,\s*\S+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*{\s*\S+\s*,\s*\S+\s*\}\s*,\s*{\s*(\S+)\s*,\s*(\S+)\s*\}\s*,\s*{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\w+\s*,\s*\"?[\.\w]+\"?\s*,\s*\"?[\.\w]+\"?\s*,\s*\d+\s*\}/iop)
912      {
913      my ($name, $c_start, $c_end) = ($1, $2, $3);
914
915      if ($short_mcu_name eq $name)
916        {
917        ${$Conf_start} = str2int($c_start);
918        ${$Conf_end}   = str2int($c_end);
919        last;
920        }
921      }
922    else
923      {
924      last;
925      }
926    }
927
928  close(LIB);
929  }
930
931#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
932# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
933#@@@@@@@@@@@@@@@@@@@@@                                  @@@@@@@@@@@@@@@@@@@@@@@@
934#@@@@@@@@@@@@@@@@@@@@  Prints the register definitions.  @@@@@@@@@@@@@@@@@@@@@@@
935#@@@@@@@@@@@@@@@@@@@@@                                  @@@@@@@@@@@@@@@@@@@@@@@@
936# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
937#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
938
939        # A bit may be more than one name. This procedure counts that how
940        # many the most of name.
941
942sub max_count_of_names_of_bit($)
943  {
944  my $Bits = $_[0];
945  my $num = 0;
946
947  for (my $i = 0; $i < 8; ++$i)
948    {
949    my $array = $Bits->[$i];
950
951    next if (! defined($array));
952
953    my $l = scalar(@{$array});
954
955    $num = $l if ($num < $l);
956    }
957
958  return $num;
959  }
960
961#-------------------------------------------------------------------------------
962
963        # There are certain bits that have the same name in other registers
964        # also. In this case, in the definitions of bit names need apply
965        # a prefix, that allows the bits to distinguish from each other.
966        # This function this need is recorded in the affected registers.
967
968sub set_bit_prefix()
969  {
970  foreach my $register (sort {versionSort($a->{NAME}, $b->{NAME})} @registers)
971    {
972    my $bits = $register->{BITNAMES};
973
974    next if (! defined($bits));
975
976    for (my $i = 0; $i < 8; ++$i)
977      {
978      my $array = $bits->[$i];
979
980      next if (! defined($array));
981
982      foreach (@{$array})
983        {
984        my $reg = $reg_refs_by_bits{$_};
985
986        if (defined($reg))
987          {
988          Log("The $_ bit of the $register->{NAME} register is occupied in $reg->{NAME} register. ($mcu)", 3);
989          $register->{NEED_PREFIX} = TRUE;
990          }
991        else
992          {
993          $reg_refs_by_bits{$_} = $register;
994          }
995        }
996      }
997    }
998  }
999
1000#-------------------------------------------------------------------------------
1001
1002        # Prints the $Index numbered $Bits of a register.
1003
1004sub print_bits($$$)
1005  {
1006  my ($Bits, $Index, $Align) = @_;
1007  my $al = ' ' x $Align;
1008
1009  for (my $i = 0; $i < 8; ++$i)
1010    {
1011    my $array = $Bits->[$i];
1012    my $str;
1013    my $bit = (defined($array) && defined($str = $array->[$Index])) ? " $str" : '';
1014
1015    Outl(align("${al}unsigned$bit", DIST_BITSIZE), ': 1;');
1016    }
1017  }
1018
1019#-------------------------------------------------------------------------------
1020
1021        # Prints all bits of a register.
1022
1023sub print_local_bitdefs($)
1024  {
1025  my $Register = $_[0];
1026  my $bits = $Register->{BITNAMES};
1027  my $head = ($Register->{NEED_PREFIX}) ? "$Register->{NAME}_" : '';
1028
1029  for (my $i = 0; $i < 8; ++$i)
1030    {
1031    my $array = $bits->[$i];
1032
1033    next if (! defined($array));
1034
1035    foreach (@{$array})
1036      {
1037      Outl(align("#define _${head}$_", DIST_DEFSIZE), sprintf('0x%02X', 1 << $i));
1038      }
1039    }
1040  }
1041
1042#-------------------------------------------------------------------------------
1043
1044        # Deletes the false or fragmentary bitfields.
1045
1046sub bitfield_filtration($)
1047  {
1048  my ($bits, $fields) = ($_[0]->{BITNAMES}, $_[0]->{BITFIELDS});
1049
1050        # Does not have a bitfields.
1051
1052  return if (! defined($fields));
1053
1054  foreach my $field_name (keys(%{$fields}))
1055    {
1056    my ($first_addr, $last_addr, $last_index);
1057    my $gr = $fields->{$field_name};
1058
1059    Log("bitfield_filtration() -- $field_name", 8);
1060
1061    if (find_bit($bits, $field_name))
1062      {
1063        # The $field_name already exists in the $bits array.
1064        # Name conflict.
1065
1066      delete($fields->{$field_name});
1067      next;
1068      }
1069
1070    @{$gr->{ADDRESSES}} = sort {$a <=> $b} @{$gr->{ADDRESSES}};
1071
1072    my ($addresses, $indexes) = ($gr->{ADDRESSES}, $gr->{INDEXES});
1073
1074    $first_addr = $addresses->[0];
1075
1076    if ((scalar(@{$addresses}) < 2) || ($indexes->[$first_addr] != 0))
1077      {
1078        # This is not field, for only one member of there is. The other
1079        # possibility is that the index of the first member is not zero.
1080
1081      delete($fields->{$field_name});
1082      next;
1083      }
1084
1085    $last_addr  = -1;
1086    $last_index = -1;
1087
1088    foreach (@{$addresses})
1089      {
1090      my $idx = $indexes->[$_];
1091
1092      if ($last_addr >= 0)
1093        {
1094        if ((($last_addr + 1) != $_) || (($last_index + 1) != $idx))
1095          {
1096        # This bitfield is fragmented (not uniform).
1097
1098          $last_addr = -1;
1099          last;
1100          }
1101        }
1102
1103      $last_addr  = $_;
1104      $last_index = $idx;
1105      }
1106
1107        # This is the width of the bitfield.
1108
1109    my $width = $last_addr - $first_addr + 1;
1110
1111    if (($width > 0) && ($width < 8))
1112      {
1113      $gr->{WIDTH} = $width;
1114      }
1115    else
1116      {
1117      delete($fields->{$field_name});
1118      }
1119    } # foreach my $field_name (keys(%{$fields}))
1120  }
1121
1122#-------------------------------------------------------------------------------
1123
1124sub print_bitfield($$$)
1125  {
1126  my ($Name, $Group, $Align) = @_;
1127  my ($addr, $width) = ($Group->{ADDRESSES}->[0], $Group->{WIDTH});
1128  my $al = ' ' x $Align;
1129
1130  Outl(align("${al}unsigned", DIST_BITSIZE), ": $addr;") if ($addr > 0);
1131  Outl(align("${al}unsigned $Name", DIST_BITSIZE), ": $width;");
1132  $width = 8 - ($addr + $width);
1133  Outl(align("${al}unsigned", DIST_BITSIZE), ": $width;") if ($width > 0);
1134  }
1135
1136#-------------------------------------------------------------------------------
1137
1138        # Prints all bits of all registers.
1139
1140sub print_all_registers()
1141  {
1142  my $fields;
1143  my @field_names;
1144  my ($bit_struct_num, $field_struct_num, $all_struct_num);
1145  my ($alias, $i, $r, $text, $type, $v);
1146
1147  $v = @registers;
1148  for ($r = 0; $r < $v;)
1149    {
1150    my $reg = $registers[$r];
1151    ++$r;
1152
1153    my ($name, $addr, $bits) = ($reg->{NAME}, $reg->{ADDRESS}, $reg->{BITNAMES});
1154
1155    if ($addr >= 0)
1156      {
1157      bitfield_filtration($reg) if ($create_bitfields);
1158
1159      $text = sprintf("__at(0x%04X)", $addr);
1160      $device_registers .= "$text __sfr $name;\n";
1161
1162      $alias = $register_aliases{$name};
1163      $alias = undef if (defined($alias) && defined($reg_refs_by_names{$alias}));
1164
1165      if (defined($bits) && (scalar(@{$bits}) > 0))
1166        {
1167        $type = "__$name$btype_t";
1168        Outl("\n$section\n//", (' ' x 8), "$name Bits\n\nextern $text __sfr $name;");
1169        Outl("\n#define $alias $name") if (defined($alias));
1170
1171        $bit_struct_num = max_count_of_names_of_bit($bits);
1172
1173        if ($create_bitfields)
1174          {
1175          $fields = $reg->{BITFIELDS};
1176          @field_names = sort {$fields->{$a}->{ADDRESSES}->[0] <=> $fields->{$b}->{ADDRESSES}->[0]} keys(%{$fields});
1177          $field_struct_num = @field_names;
1178          $all_struct_num = $bit_struct_num + $field_struct_num - 1;
1179          }
1180        else
1181          {
1182          $all_struct_num = $bit_struct_num - 1;
1183          }
1184
1185        if ($all_struct_num > 0)
1186          {
1187          Outl("\ntypedef union\n  {");
1188
1189          for ($i = 0; $i < $bit_struct_num; ++$i)
1190            {
1191            Outl("  struct\n    {");
1192            print_bits($bits, $i, 4);
1193            Outl('    };');
1194            Outl() if ($all_struct_num);
1195            --$all_struct_num;
1196            }
1197
1198          if ($create_bitfields)
1199            {
1200            for ($i = 0; $i < $field_struct_num; ++$i)
1201              {
1202              my $flname = $field_names[$i];
1203
1204              Outl("  struct\n    {");
1205              print_bitfield($flname, $fields->{$flname}, 4);
1206              Outl('    };');
1207              Outl() if ($all_struct_num);
1208              --$all_struct_num;
1209              }
1210            }
1211          }
1212        else
1213          {
1214          Outl("\ntypedef struct\n  {");
1215          print_bits($bits, 0, 2);
1216          }
1217
1218        Outl("  } $type;");
1219        Outl("\nextern $text volatile $type $name$btail;");
1220        Outl("\n#define $alias$btail $name$btail") if (defined($alias));
1221        Outl();
1222        print_local_bitdefs($reg);
1223        Outl("\n$section\n");
1224
1225        $device_registers .= "$text volatile $type $name$btail;\n";
1226        } # if (defined($bits) && (scalar(@{$bits}) > 0))
1227      else
1228        {
1229        Outl("extern $text __sfr $name;");
1230        Outl("#define $alias $name") if (defined($alias));
1231        }
1232
1233      $device_registers .= "\n" if ($r < $v);
1234      } # if ($addr >= 0)
1235    elsif (defined($bits) && (scalar(@{$bits}) > 0))
1236      {
1237        # This is a register which can not be achieved directly, but the bits has name.
1238
1239      Outl("\n$section\n//", (' ' x 8), "$name Bits\n");
1240      print_local_bitdefs($reg);
1241      Outl("\n$section\n");
1242      }
1243    } # for ($r = 0; $r < $v;)
1244  }
1245
1246#-------------------------------------------------------------------------------
1247
1248sub print_configuration_words()
1249  {
1250  if (! scalar(@configs))
1251    {
1252        # PIC18FxxJ
1253
1254    my ($start, $end) = (-1, -1);
1255
1256    extract_config_area(\$start, \$end);
1257    return if (($start < 0) || ($end < 0));
1258
1259    Outl("\n$section\n//\n//", (' ' x 8), "Configuration Addresses\n//\n$section\n");
1260
1261    my $i = 0;
1262    while ($start <= $end)
1263      {
1264      my $n = int($i / 2) + 1;
1265      my $h = ($i & 1) ? 'H' : 'L';
1266
1267      Out(align("#define ${conf_head}CONFIG$n$h", DIST_BITSIZE));
1268      Outl(sprintf("0x%0${caddr_size}X", $start));
1269      ++$i;
1270      ++$start;
1271      }
1272
1273    Outl("\n$section\n");
1274    return;
1275    }
1276
1277  Outl("\n$section\n//\n//", (' ' x 8), "Configuration Bits\n//\n$section\n");
1278
1279  foreach (@configs)
1280    {
1281    Out(align("#define $conf_head$_->{NAME}", DIST_BITSIZE));
1282    Outl(sprintf("0x%0${caddr_size}X", $_->{ADDRESS}));
1283    }
1284
1285  foreach (@configs)
1286    {
1287    next if (! @{$_->{OPTIONS}});
1288
1289    Outl("\n//", ('-' x 29), " $_->{NAME} Options ", ('-' x 31), "\n");
1290
1291    foreach (@{$_->{OPTIONS}})
1292      {
1293      my $expl = $_->{EXPLANATION};
1294
1295        # Improve a spelling error: On the end of a sentence a point must be.
1296      $expl .= '.' if (($expl ne '') && ($expl !~ /\.$/o));
1297
1298      Out(align("#define $_->{NAME}", DIST_BITSIZE));
1299      Out(align(sprintf("0x%0${conf_size}X", $_->{VALUE}), 8));
1300      Out("// $expl") if (defined($expl) && ($expl ne ''));
1301      Outl();
1302      }
1303    }
1304
1305  Outl("\n$section\n");
1306  }
1307
1308#-------------------------------------------------------------------------------
1309
1310sub print_devids_and_idlocs()
1311  {
1312  foreach (\@devids, \@idlocs)
1313    {
1314    if (scalar(@{$_}) > 0)
1315      {
1316      foreach (@{$_})
1317        {
1318        Out(align("#define $conf_head$_->{NAME}", DIST_BITSIZE));
1319        Outl(sprintf("0x%0${caddr_size}X", $_->{ADDRESS}));
1320        }
1321
1322      Outl();
1323      }
1324    }
1325  }
1326
1327#-------------------------------------------------------------------------------
1328
1329sub print_license($)
1330  {
1331  print $out_handler <<EOT
1332/*
1333 * This $_[0] of the $mcu MCU.
1334 *
1335 * This file is part of the GNU PIC library for SDCC, originally
1336 * created by Molnar Karoly <molnarkaroly\@users.sf.net> $year.
1337 *
1338 * This file is generated automatically by the $PROGRAM${time_str}.
1339 *
1340 * SDCC is licensed under the GNU Public license (GPL) v2. Note that
1341 * this license covers the code to the compiler and other executables,
1342 * but explicitly does not cover any code or objects generated by sdcc.
1343 *
1344 * For pic device libraries and header files which are derived from
1345 * Microchip header (.inc) and linker script (.lkr) files Microchip
1346 * requires that "The header files should state that they are only to be
1347 * used with authentic Microchip devices" which makes them incompatible
1348 * with the GPL. Pic device libraries and header files are located at
1349 * non-free/lib and non-free/include directories respectively.
1350 * Sdcc should be run with the --use-non-free command line option in
1351 * order to include non-free header files and libraries.
1352 *
1353 * See http://sdcc.sourceforge.net/ for the latest information on sdcc.
1354 */
1355
1356EOT
1357;
1358  }
1359
1360#-------------------------------------------------------------------------------
1361
1362        # This procedure generates the pic14-specific information.
1363
1364sub make_pic14_dependent_defs()
1365  {
1366  foreach (sort {versionSort($a->{NAME}, $b->{NAME})} @registers)
1367    {
1368    my ($name, $bits) = ($_->{NAME}, $_->{BITNAMES});
1369    my $prefix = "$name$btail";
1370
1371    if ($emit_legacy_names)
1372      {
1373      $legacy_names .= align("#define ${name}_$btail", DIST_DEFSIZE);
1374      $legacy_names .= "$prefix\n";
1375      }
1376
1377    next if ($_->{NEED_PREFIX} || ! defined($bits));
1378
1379    for (my $i = 0; $i < 8; ++$i)
1380      {
1381      my $array = $bits->[$i];
1382
1383      next if (! defined($array));
1384
1385      my $shadow = (scalar(@{$array}) > 1) ? ", shadows bit in $prefix" : '';
1386
1387      foreach (@{$array})
1388        {
1389        $full_bitdefs .= align("#define $_", DIST_DEFSIZE);
1390        $full_bitdefs .= align("$prefix.$_", DIST_COMSIZE);
1391        $full_bitdefs .= "// bit $i$shadow\n";
1392        }
1393      }
1394
1395    $full_bitdefs .= "\n";
1396    }
1397
1398  $legacy_names .= "\n";
1399  }
1400
1401#-------------------------------------------------------------------------------
1402
1403        # Prints all informations to the header file.
1404
1405sub print_to_header_file()
1406  {
1407  my ($text, $name, $address, $str);
1408
1409  print_license('declarations');
1410  Outl("#ifndef __${mcu}_H__\n#define __${mcu}_H__\n\n$section");
1411
1412  if (! $is_pic16)
1413    {
1414    $text = '#ifndef NO_ADDR_DEFINES';
1415
1416    Outl("//\n//\tRegister Addresses\n//\n$section\n\n$text\n");
1417
1418    foreach (sort { $a->{ADDRESS} <=> $b->{ADDRESS} } @registers)
1419      {
1420      ($name, $address) = ($_->{NAME}, $_->{ADDRESS});
1421      next if ($address < 0);
1422
1423      $str = sprintf('0x%04X', $address);
1424      Outl(align("#define ${name}_ADDR", DIST_ADDRSIZE), $str);
1425      }
1426
1427    Outl("\n#endif // $text");
1428    }
1429
1430  Outl("\n$section\n//\n//\tRegister Definitions\n//\n$section\n");
1431  set_bit_prefix();
1432  print_all_registers();
1433  print_configuration_words();
1434  print_devids_and_idlocs();
1435
1436  if (! $is_pic16)
1437    {
1438    make_pic14_dependent_defs();
1439    Outl("$section\n");
1440
1441    if ($full_bitdefs ne '')
1442      {
1443      $text = '#ifndef NO_BIT_DEFINES';
1444      Outl("$text\n\n", $full_bitdefs, "#endif // $text\n");
1445      }
1446
1447    if ($emit_legacy_names)
1448      {
1449      $text = '#ifndef NO_LEGACY_NAMES';
1450      Outl("$text\n\n", $legacy_names, "#endif // $text\n");
1451      }
1452    }
1453
1454  Outl("#endif // #ifndef __${mcu}_H__");
1455  }
1456
1457#-------------------------------------------------------------------------------
1458
1459        # Prints name of all registers to the device file.
1460
1461sub print_to_device_file()
1462  {
1463  print_license('definitions');
1464  Outl("#include <$header_name>\n\n$section\n");
1465  Out($device_registers) if ($device_registers ne '');
1466  }
1467
1468#-------------------------------------------------------------------------------
1469
1470sub usage()
1471  {
1472  print <<EOT
1473Usage: $PROGRAM [options]
1474
1475    Options are:
1476
1477        -gp <path> or --gputils-path <path>
1478
1479            The program on this path looks for the gputils source package.
1480
1481        -I <path> or --include <path>
1482
1483            The program on this path looks for the headers (inc files). If this
1484            not specified, then the "header" directory in the local repository
1485            will be the default.
1486
1487        -p <p12f1822> or --processor <p12f1822>
1488
1489            The name of MCU. The prefix of name can be: 'p', 'pic' or nothing
1490
1491        -o <path> or --out-path <path>
1492
1493            Here to writes the output files. (default: "./")
1494            Attention! The program overwrites the existing files without asking.
1495
1496        -v <level> or --verbose <level>
1497
1498            It provides information on from the own operation.
1499            Possible value of the level between 0 and 10. (default: 0)
1500
1501        -cb or --create-bitfields
1502
1503            Create bit fields. In some register, can be found such bits which
1504            belong together. For example: CVR0, CVR1, CVR2, CVR3
1505            These may be useful, to merge during a common field name: CVR
1506            The compiler helps handle these bit fields. (default: no)
1507
1508        -e or --emit-legacy-names
1509
1510            Creates the legacy names also. (default: no)
1511
1512        -nt or --no-timestamp
1513
1514            There will be no timestamp in the header and device files. (default: yes)
1515
1516        -h or --help
1517
1518            This text.
1519
1520    For example: $PROGRAM -p 12f1840 -cb
1521EOT
1522;
1523  }
1524
1525#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1526# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1527#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1528#@@@@@@@@@@@@@@@@@@@@@@@@@@@@  The main program.  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1529#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1530# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1531#   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1532
1533$PROGRAM = basename($0);
1534$gp_header_path = '';
1535$mcu = '';
1536
1537for (my $i = 0; $i < scalar(@ARGV); )
1538  {
1539  my $opt = $ARGV[$i++];
1540
1541  given ($opt)
1542    {
1543    when (/^-(gp|-gputils-path)$/o)
1544      {
1545      param_exist($opt, $i);
1546      $gputils_path = $ARGV[$i++];
1547      }
1548
1549    when (/^-(I|-include)$/o)
1550      {
1551      param_exist($opt, $i);
1552      $gp_header_path = $ARGV[$i++];
1553      }
1554
1555    when (/^-(p|-processor)$/o)
1556      {
1557      param_exist($opt, $i);
1558      $mcu = $ARGV[$i++];
1559      }
1560
1561    when (/^-(o|-out-path)$/o)
1562      {
1563      param_exist($opt, $i);
1564      $out_path = $ARGV[$i++];
1565      }
1566
1567    when (/^-(v|-verbose)$/o)
1568      {
1569      param_exist($opt, $i);
1570      $verbose = int($ARGV[$i++]);
1571      $verbose = 0 if (! defined($verbose) || ($verbose < 0));
1572      $verbose = 10 if ($verbose > 10);
1573      }
1574
1575    when (/^-(cb|-create-bitfields)$/o)
1576      {
1577      $create_bitfields = TRUE;
1578      }
1579
1580    when (/^-(e|-emit-legacy-names)$/o)
1581      {
1582      $emit_legacy_names = TRUE;
1583      }
1584
1585    when (/^-(nt|-no-timestamp)$/o)
1586      {
1587      $no_timestamp = TRUE;
1588      }
1589
1590    when (/^-(h|-help)$/o)
1591      {
1592      usage();
1593      exit(0);
1594      } # when ('-h' || '--help')
1595    } # given ($opt)
1596  }
1597
1598die "Miss the name of MCU!\n" if ($mcu eq '');
1599die "This name is wrong: \"$mcu\"\n" if ($mcu !~ /^(p(ic)?)?$name_filter$/io);
1600
1601die "This directory - $gputils_path - not exist!" if (! -d $gputils_path);
1602
1603$gp_header_path = "$gputils_path/header" if ($gp_header_path eq '');    # The default value.
1604$gpproc_path    = "$gputils_path/libgputils/$gpprocessor_c";
1605
1606$mcu = lc($mcu);
1607$mcu =~ s/^p(ic)?//o;
1608
1609if ($mcu =~ /^18/)
1610  {
1611  $is_pic16   = TRUE;
1612  $conf_size  = 2;
1613  $caddr_size = 6;
1614  $conf_head  = '__';
1615  }
1616
1617$short_mcu_name = $mcu;
1618my $fname = "p${mcu}.inc";
1619
1620die "The MCU: $mcu unknown!\n" if (! -f "$gp_header_path/$fname");
1621
1622$mcu = 'PIC' . uc($mcu);
1623$header_name = lc($mcu) . '.h';
1624$device_name = lc($mcu) . '.c';
1625
1626read_content_from_header("$gp_header_path/$fname");
1627
1628$year     = strftime('%Y', gmtime);
1629$time_str = strftime(', %F %T UTC', gmtime) if (! $no_timestamp);
1630
1631        # Creates the directory structure.
1632
1633my $path = ($is_pic16) ? "$out_path/$p16_out_path" : "$out_path/$p14_out_path";
1634my $head_dir = "$path/header";
1635
1636if (! -e $head_dir)
1637  {
1638  Log("Creates the \"$head_dir\" dir.", 4);
1639  make_path($head_dir) || die "Could not create the \"$head_dir\" dir!";
1640  }
1641
1642my $dev_dir = "$path/device";
1643
1644if (! -e $dev_dir)
1645  {
1646  Log("Creates the \"$dev_dir\" dir.", 4);
1647  make_path($dev_dir) || die "Could not create the \"$dev_dir\" dir!";
1648  }
1649
1650        # Creates the pic1xxxx.h file.
1651
1652my $fpath = "$head_dir/$header_name";
1653open($out_handler, '>', $fpath) || die "Could not create the \"$fpath\" file!\n";
1654Log("Creates the $header_name", 1);
1655print_to_header_file();
1656close($out_handler);
1657
1658        # Creates the pic1xxxx.c file.
1659
1660$fpath = "$dev_dir/$device_name";
1661open($out_handler, '>', $fpath) || die "Could not create the \"$fpath\" file!\n";
1662Log("Creates the $device_name", 1);
1663print_to_device_file();
1664close($out_handler);
1665