Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
# -*- mode: perl; tabs: 8; indent-width: 4; show-tabs: yes; -*-
2
# Copyright (C) 1998-2004 ERG Transit Systems, All rights reserved
3
#
4
# Module name   : mos_mri
5
# Module type   : Makefile system
6
# Compiler(s)   : ANSI C
7
# Environment(s): MOS
8
#
9
# Description:
10
#       MRI 68k/CF toolset for MOS
11
#       This file provides Toolset initialisation and plugin functions
12
#       to makelib.pl2
13
#
14
# Contents:     MRI 68k/CF rules as used for the MOS
15
#
16
# Revision History:
17
#       12-Feb-04   DDP     Started Work
18
#............................................................................#
19
 
20
use strict;
21
use warnings;
22
 
23
#
24
#   Toolset Global variables
25
#
26
my $Toolset_DebugCode;
27
my $Toolset_DebugData;
28
my $Toolset_Product = '';
239 dpurdie 29
my $Toolset_Production_Only;
227 dpurdie 30
 
31
 
32
##############################################################################
33
#   ToolsetInit()
34
#       Runtime initialisation
35
#
36
##############################################################################
37
 
38
ToolsetInit();
39
 
40
sub ToolsetInit
41
{
42
    my( $version, $flavour );
43
    my $no_defines;
44
    my( @defines );
45
    my $board = '';
46
 
47
#.. Parse Toolset arguments
48
#
49
    Debug( "mos_mri(@::ScmToolsetArgs)\n" );
50
 
51
    $version = 0;                               # Default (not great)
52
    $flavour = '68k';
53
    foreach $_ ( @::ScmToolsetArgs ) {
54
        if (/^--Version=(.*)/) {                # Compiler version
55
            $version = "$1";
56
        } elsif (/^--68k/) {                    # Compiler flavour
57
            $flavour = '68k';
58
        } elsif (/^--coldfire/) {               # Compiler flavour
59
            $flavour = 'cf';
60
        } elsif (/^--NoDefines/) {               # Vanila defines
61
            $no_defines = 1;
62
        } else {
63
            Message( "mos_mri: unknown toolset argument $_ -- ignored" );
64
        }
65
    }
66
 
67
#.. Parse Platform Arguments
68
#
69
    foreach $_ ( @::ScmPlatformArgs ) {
70
        if (/^--product=(.*)/) {                # GBE product
71
            $Toolset_Product = $1;
72
        } elsif (/^--board=(.*)/) {             # Board subtypes
73
            $board = $1;
74
        } else {
75
            Message( "mos_mri: unknown platform argument $_ -- ignored" );
76
        }
77
    }
78
 
79
#
239 dpurdie 80
#   Is this a ProductionOnly build, then we don't need the debug code and data
81
#   when building a THX. Determine, if this is a ProductionOnly build.
82
#
83
foreach  ( @{$::BUILDINFO{$::ScmPlatform}{ARGS}} )
84
{
85
    if ( m~^--OnlyProd~ )
86
    {
87
        $Toolset_Production_Only = 1;
88
        last;
89
    }
90
}
91
 
92
#
227 dpurdie 93
#   Definitions common to all platforms
94
#   These will be picked up when no platform has been defined: ie when
95
#   simply building for MOS68K or MOSCF
96
#
97
#   Note: _MICROTEC     is predefined by the compiler
98
#
99
    unless ( $no_defines )
100
    {
101
        push @defines, 'MOS';
102
        push @defines, '_MOS';
103
        push @defines, '_MOS_=1';
104
        push @defines, '_MOS_PERTH_=1';
105
        push @defines, 'MICROTEC=1';
106
        push @defines, 'MRI=1';
107
        push @defines, 'BIG_ENDIAN=1';
108
        push @defines, 'CcCpuBigEndian=1';
109
        push @defines, 'CcSupervisor=$(MODE_CCSUPERVISOR)';
110
        push @defines, 'CcCpu=$(mri_cpu_code)';
111
    }
112
 
113
#
114
#   Platform specific definitions
115
#   Set default code and data for development purposes only
116
#   This can be overridden
117
#
118
    if ( $Toolset_Product eq "GAK" || $Toolset_Product eq "TPT" )
119
    {
120
        # Example only
121
        #push @defines, '	SSM_DV';
122
        #push @defines, '	DES_ALIGN_CHECK';
123
        #push @defines, '	AMCCIF=15';
124
        #push @defines, '	PACKED=packed';
125
 
126
        if ( $flavour eq  '68k' )
127
        {
128
            $Toolset_DebugCode = "08100000H";
129
            $Toolset_DebugData = "0800800CH";
130
        }
131
        else
132
        {
133
            $Toolset_DebugCode = "08200000H";
134
            $Toolset_DebugData = "0800800CH";
135
        }
136
    }
137
    elsif ( $Toolset_Product eq "PCP" )
138
    {
139
        $board = "08200000H,0800800CH" if ( $board =~ m/development/i );
140
        $Toolset_DebugCode = "08100000H";
141
        $Toolset_DebugData = "0800800CH";
142
    }
143
    elsif ( $Toolset_Product eq "VCP" )
144
    {
145
        $Toolset_DebugCode = "08100000H";
146
        $Toolset_DebugData = "0800800CH";
147
    }
148
    elsif ( $Toolset_Product eq "TP5" )
149
    {
150
        $board = "08000000H,0400800CH" if ( $board =~ m/green/i );
151
        $Toolset_DebugCode = "05C00000H";
152
        $Toolset_DebugData = "0400800CH";
153
    }
154
    elsif ( $Toolset_Product eq "SSU" )
155
    {
156
    #    $Toolset_DebugCode = "08100000H";
157
    #    $Toolset_DebugData = "0800800CH";
158
    }
159
    elsif ( $Toolset_Product eq "DDU" )
160
    {
161
    #    $Toolset_DebugCode = "08100000H";
162
    #    $Toolset_DebugData = "0800800CH";
163
    }
164
    elsif ( $Toolset_Product eq "HCP" )
165
    {
166
    #    $Toolset_DebugCode = "08100000H";
167
    #    $Toolset_DebugData = "0800800CH";
168
    }
169
    elsif ( $Toolset_Product eq "OBFTP" )
170
    {
171
        $Toolset_DebugCode = "08200000H";
172
        $Toolset_DebugData = "0800800CH";
173
    }
174
    elsif ( $Toolset_Product )
175
    {
176
        Message( "mos_mri: Unknown product: $Toolset_Product -- ignored" );
177
    }
178
 
179
    #
180
    #   Decode any --board option
181
    #   This will override any defaults
182
    #
183
    if ($board )
184
    {
185
        if ( $board =~ m~(0[0-9A-F]+H),(0[0-9A-F]+H)~i )
186
        {
187
            $Toolset_DebugCode = $1;
188
            $Toolset_DebugData = $2;
189
            Message("Building for a $Toolset_Product DEVELOPMENT board: Code:$Toolset_DebugCode, Data:$Toolset_DebugData");
190
        }
191
        else
192
        {
193
            Error( "Bad board definition: $board",
194
                   "Expecting two hex numbers of the form 012345H" );
195
        }
196
    }
197
 
198
 
199
if ( $Toolset_Product && (! $Toolset_DebugCode || ! $Toolset_DebugData ))
200
{
201
    Message( "mos_mri: $Toolset_Product: Debug Code and Data not specified" );
202
}
203
 
204
#.. Standard.rul requirements
205
#
206
    $::s = 'asm';             # Assembler source file
207
    $::o = 'obj';             # Object file
208
    $::a = 'lib';             # Library file
209
    $::so = 'thx';            # Shared library
210
    $::exe = '.abs';          # Dummy, Cannot generate executables
211
 
212
#.. Toolset configuration
213
#
214
    $::ScmToolsetVersion = "1.0.0";               # our version
215
    $::ScmToolsetGenerate = 0;                    # generate optional
216
 
217
#.. Define MRI environment
218
#
219
    #
220
    #   Define initialisation targets
221
    #   These will be used to ensure that correct versions of the toolset are present
222
    #
223
    Init( "mri", "mri2" );
224
 
225
    ToolsetDefine ( "#################################################" );
226
    ToolsetDefine ( "# MOS MRI compiler version" );
227
    ToolsetDefine ( "#" );
228
    ToolsetDefine ( "mri_ver         = $version" );
229
    ToolsetDefine ( "mri_type        = $flavour" );
230
    ToolsetDefine ( "" );
231
    ToolsetDefine ( "#" );
232
    ToolsetDefines( "mos_mri_${flavour}.def" );
233
    ToolsetRules  ( "mos_mri.rul" );
234
    ToolsetRules  ( "standard.rul" );
235
 
236
    PlatformEntry( "MRI_DEFINES\t=",    "\n", "\\\n\t", "", @defines )
237
        if ( scalar @defines );
238
 
239
    #
240
    #   Other toolsets used
241
    #
242
    PlatformDefine ("LINT_COFILE\t= MOS_MRI.LNT");
243
    PlatformDefine ("LINT_PRJ_FILE\t=lint.mri");
244
    ToolsetRequire( "pclint" );                 # using pclint
245
 
246
#
247
#   The debug files need to be compiled up with absolute paths to the source files
248
#   The easiest way to do this is with the makefile rules created with absolute
249
#   paths. Set a global flag to enable this option
250
#
251
    $::UseAbsObjects = 1;
252
 
253
 
254
#.. Extend the CompilerOption directive
255
#   Create a standard data structure
256
#   This is a hash of hashes
257
#       The first hash is keyed by CompileOption keyword
258
#       The second hash contains pairs of values to set or remove
259
#
260
    %::ScmToolsetCompilerOptions =
261
    (
262
        'ccsupervisor'          => { 'MODE_CCSUPERVISOR' , '1' },
263
 
264
        #
265
        #   When using MOS fast intermodule calls the optimizer will preload commonly
266
        #   used memory addresses into a register BEFORE the GDP has been correctly set
267
        #   up. Use the following option to supress this optimisation
268
        #
269
        'noglobaloptimization'  => { 'NO_OPT_GLOBAL' , '1' },
270
 
271
        #
272
        #   To enable 32-bit relative PC addressing on platforms that
273
        #   don't have this as a default
274
        #
275
        'longrelative'    => { 'USE_32BIT_RELATIVE' , '1' },
276
        'nolongrelative'  => { 'USE_32BIT_RELATIVE' , undef },
277
 
278
    );
279
 
280
    #
281
    #   Set default options
282
    #       $::ScmCompilerOpts{'xxxx'} = 'yyy';
283
    $::ScmCompilerOpts{'MODE_CCSUPERVISOR'} = '0';
284
    $::ScmCompilerOpts{'NO_OPT_GLOBAL'} = undef;
285
    $::ScmCompilerOpts{'USE_32BIT_RELATIVE'} = undef;
286
}
287
 
288
##############################################################################
289
#   ToolsetPreprocess()
290
#       Process collected data before the makefile is generated
291
#       This, optional, routine is called from within MakefileGenerate()
292
#       It allows the toolset to massage any of the collected data before
293
#       the makefile is created
294
#
295
##############################################################################
296
 
297
sub ToolsetPreprocess
298
{
299
    #
300
    #   If the user has specified a Prog or Shared library, then the
301
    #   tools within this file will need to be able to access
302
    #   a few external resouces. These will be provided by packages
303
    #   that should exist
304
    #
305
    #
306
    if ( $#::TESTPROGS >= 0 || $#::PROGS >= 0 || $#::SHLIBS >= 0)
307
    {
308
        my %need = ( "brt.exe"          => "TOOL_BRT",
309
                     "modcrc.exe"       => "TOOL_MODCRC",
310
                     "rel.exe"          => "TOOL_REL",
311
                     "vclickpaths.exe"  => "TOOL_VPATHS"
312
                   );
313
        my %found = ();
314
 
315
        #
316
        #   Locate the required files
317
        #
318
        for my $program ( keys( %need ))
319
        {
320
            if ( my $path = ToolExtensionProgram( $program ) )
321
            {
322
                $found{ $need{$program} } = $path;
323
                delete( $need{$program} );
324
            }
325
        }
326
 
327
        ::Error( "Tool program(s) required by toolset not found:",
328
                  sort( keys %need),
329
                  "Check that the daf_tools and mos_tools packages are present" )
330
            if ( scalar keys %need );
331
 
332
        #
333
        #   Generate the definitions
334
        #
335
 
336
        ToolsetDefine ( "#################################################" );
337
        ToolsetDefine ( "#  The path to tools required to build MOS Programs" );
338
        ToolsetDefine ( "#" );
339
        for my $defn ( keys %found )
340
        {
341
            ToolsetDefine ( "$defn := $found{$defn}" );
342
        }
343
        ToolsetDefine ( "" );
344
        ToolsetDefine ( "#  The drive path to prefix to the vision click paths" );
345
        EnvImport( "GBE_DRV" );
346
        ToolsetDefine ( "GBE_VCLICKDRV = $::GBE_DRV" );
347
    }
348
}
349
 
350
###############################################################################
351
#   ToolsetCC( $source, $obj, \@args )
352
#       This subroutine takes the user options and builds the rule(s)
353
#       required to compile the source file 'source' to 'obj'
354
#
355
#   Implementation Note:
356
#   The MRI compilers that are being used have a problem.
357
#   If the source filename is relative and longer that ~80 characters and the
358
#   -Gf switch is being used, then the compiler warns that the pathname is
359
#   too long to be stored in the ABS file. It then stores the relative name to
360
#   the file in thr ABS file. This confuses visionclick and vclickpaths
361
#
362
#   If the source file is an absolute path, then none of these problems
363
#   occur, BUT the displayed error messages get chopped so that the user
364
#   cannot determine the file being compiled.
365
#
366
#   Solution:
367
#       * Give the compiler an absolute path name
368
#       * Display a shortened filename on the JATS output
369
#
370
###############################################################################
371
 
372
sub ToolsetCC
373
{
374
    MakePrint( "\n\t\$(CC)\n" );
375
}
376
 
377
###############################################################################
378
#   ToolsetCCDepend( $depend, \@sources )
379
#       This subroutine takes the user options and builds the
380
#       rule(s) required to build the dependencies for the source
381
#       files 'sources' to 'depend'.
382
#
383
###############################################################################
384
 
385
sub ToolsetCCDepend
386
{
387
    MakePrint( "\t\$(CCDEPEND)\n" );
388
}
389
 
390
 
391
###############################################################################
392
#   ToolsetCXX( $source, $obj, \@args )
393
#       This subroutine takes the user options and builds the rule(s)
394
#       required to compile the source file 'source' to 'obj'
395
#
396
###############################################################################
397
 
398
sub ToolsetCXX
399
{
400
    MakePrint( "\n\t\$(CXX)\n" );
401
}
402
 
403
###############################################################################
404
#   ToolsetCXXDepend( $depend, \@sources )
405
#       This subroutine takes the user options and builds the
406
#       rule(s) required to build the dependencies for the source
407
#       files 'sources' to 'depend'.
408
#
409
###############################################################################
410
 
411
sub ToolsetCXXDepend
412
{
413
    #ToolsetCCDepend() handles both CC and CXX source
414
}
415
 
416
 
417
###############################################################################
418
#   ToolsetAS( $source, $obj, \@args )
419
#       This subroutine takes the user options and builds the rule(s)
420
#       required to compile the source file 'source' to 'obj'
421
#
422
###############################################################################
423
 
424
sub ToolsetAS
425
{
426
    MakePrint( "\n\t\$(AS)\n" );
427
}
428
 
429
sub ToolsetASDepend
430
{
431
}
432
 
433
###############################################################################
434
#   ToolsetAR( $name, \@args, \@objs )
435
#       This subroutine takes the user options and builds the rules
436
#       required to build the library 'name'.
437
 
438
#
439
#   Arguments:
440
#       --xxx                   No arguments currently defined
441
#
442
#   Output:
443
#       [ $(BINDIR)/name$.${a}:   .... ]
444
#           $(AR)
445
#
446
###############################################################################
447
 
448
sub ToolsetAR
449
{
450
    my( $name, $pArgs, $pObjs ) = @_;
451
    my $lib_file = "${name}\$(GBE_TYPE)";
452
    my $lib_base = "\$(LIBDIR)/$lib_file";
453
    my $lib_name = "$lib_base.${a}";
454
 
455
    Debug("ToolsetAR");
456
 
457
#.. Parse arguments
458
#
459
    foreach $_ ( @$pArgs ) {
460
        if (/^--/) {
461
            Message( "AR: unknown option $_ -- ignored" );
462
        }
463
    }
464
 
465
#.. Target
466
#
467
    MakeEntry( "$lib_name:\t", "", "\\\n\t\t", ".$::o", @$pObjs );
468
    MakePrint( "\n\t\$(AR)\n\n" );
469
 
470
}
471
 
472
###############################################################################
473
#   ToolsetARLINT( $name, \@args, \@objs )
474
#       This subroutine takes the user options and builds the rules
475
#       required to build the library 'name'.
476
#
477
#   Arguments:
478
#       --xxx                   No arguments currently defined
479
#
480
#   Output:
481
#       [ $(LIBDIR)/name$_lint:   .... ]
482
#           $(ARLINT)
483
#
484
###############################################################################
485
 
486
sub ToolsetARLINT
487
{
488
    PCLintAR( @_ );
489
}
490
 
491
###############################################################################
492
#   ToolsetARMerge()
493
#       Generate the recipe to merge libraries.
494
#       The dependency list is created by the caller.
495
#
496
###############################################################################
497
 
498
sub ToolsetARMerge
499
{
500
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
501
}
502
 
503
 
504
###############################################################################
505
#   ToolsetSHLD $name, \@args, \@objs, \@libraries )
506
#       This subroutine takes the user options and builds the rules
507
#       required to link a shared library with any associated stub files
508
#
509
#   Arguments:
510
#       --xxx                   No Arguments currently specified
511
#
512
#       Linker specific:
513
#       --Data                  Generate a Data Module
514
#       --Debug                 Generate a debug module
515
#       --DebugCode=nnnnnH      Generate a debug module with code at address
516
#       --DebugData=nnnnnH      Generate a debug module with data at address
517
#       --Rel=file              Specify the Release file
518
#       --Implib=objfile        Specify an import library object
519
#       --StubOnly              Only generate the stub library
520
#       --BinaryImage           Generate binary image instead of a THX file
521
#
522
#   Output:
523
#
524
#       name.thx                - Loadable module
525
#       name.lib                - Module interface stub library
526
#       name.abs                - Precursor to .thx
527
#       name_o.abs              - Used to generate relocation information
528
#       name_0.abs              - Used to generate relocation information
529
#
530
#       name_debug.bdx          - File for debugger
531
#       name_debug.ab           - File for debugger
532
#       name_debug.abs          - Precursor to .bdx and .ab files
533
#
534
#       This is a very complicated process:
535
#           Generate stub library
536
#           Create module header object file
537
#           Link all at one address
538
#           Link all at another address
539
#           Determine relocation information
540
#           Compile up relocation information
541
#           Link all with relocation information
542
#           Create VisionClick debug files
543
#           Generate CRC over module
544
#
545
#   $(LIBDIR)/name.thx $(BINDIR)/name.bdx $(BINDIR)/name.ab :
546
#                       $(BINDIR)/name.abs
547
#
548
#   $(LIBDIR)/name.abs :
549
#                       objs ....
550
#                       libs ....
551
#                       $(OBJDIR)/linker_cmd_file
552
#
553
#   $(LIBDIR)/linker_cmd_file :
554
#                       $(GBE_PLATFORM).mk
555
#                       ...
556
###############################################################################
557
 
558
sub ToolsetSHLD
559
{
560
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
561
    my $module_type = '';
562
    my $debug_code = $Toolset_DebugCode || 0;
563
    my $debug_data = $Toolset_DebugData || 0;
564
    my( $u_rel_file, $rel_file, $head_file, $implib, $stub_only, $bin_image);
565
    my $pSlibs;
566
 
567
 
568
#.. Parse arguments
569
#
570
    foreach $_ ( @$pArgs )
571
    {
572
 
573
    #.. Target specific
574
    #
575
 
576
    #.. Toolset specific
577
    #
578
        if (/^--Data$/) {                       # Generate a data module
579
            $module_type  = "data";
580
 
581
        } elsif (/^--Acon$/) {                  # Generate an ACON  module
582
            $module_type  = "acon";
583
 
584
        } elsif (/^--Rel=(.*)/) {               # The base REL file
585
            $u_rel_file = $1;
586
 
587
        } elsif (/^--Implib=(.*)/) {            # The import library object file
588
            $implib = $1;
589
 
590
        } elsif (/^--Stubonly/) {               # Only generate the stub library
591
            $stub_only = 1;
592
 
593
        } elsif (/^--BinaryImage/) {            # Generate binary image instead of a THX file
594
            $bin_image = 1;
595
 
596
        } elsif (/^--DebugData=(.*)/) {         # Generate a debug module
597
            $debug_data = $1;
598
            $module_type  = "debug";
599
 
600
        } elsif (/^--DebugCode=(.*)/) {         # Generate a debug module
601
            $debug_code = $1;
602
            $module_type  = "debug";
603
 
604
        } else {
605
            Message( "Prog: unknown option $_ -- ignored" );
606
        }
607
    }
608
 
609
#
239 dpurdie 610
#   Cannot create binaries unless we know where to place them
227 dpurdie 611
#   This error could be detected earlier, but by detecting it only when
612
#   we need the values so that we can add new product groups without
613
#   knowning all the details.
614
#
239 dpurdie 615
unless ( $Toolset_Production_Only )
616
{
617
    Error( "mos_mri: $Toolset_Product: Debug Code and Data not specified" )
618
        if ( ! $debug_data || ! $debug_code );
227 dpurdie 619
 
239 dpurdie 620
}
227 dpurdie 621
 
622
#
623
#   Sanity check
624
#       - Ensure the use has provided a REL file
625
#
626
unless ( $u_rel_file )
627
{
628
    $u_rel_file = "$name.rel";
629
    Warning( "Prog: Rel file not provided. Using $u_rel_file" );
630
}
631
 
632
#
633
#   Locate the true path of the provided REL file
634
#   If it is a generate file so it will be in the SRCS hash
635
#   Other wise the use will have to use Src to locate the file
636
#
637
    $rel_file = MakeSrcResolve ( $u_rel_file );
638
 
639
#
640
#   Locate the true path of the head.asm file
641
#   This WILL be located within an external package as it is provided
642
#   by the MOS hardware package.
643
#
644
    $head_file = MakeSrcResolveExtended ( 1, "head.asm" );
645
 
646
#
647
#   If we are also creating an import (stub) library then remove
648
#   the stub library object file from the list of user provided objects
649
#   Done to allow the use of @OBJS in a library object list
650
#
651
if ( $implib )
652
{
653
    my @newobjs;
654
    for ( @$pObjs )
655
    {
656
        push @newobjs, $_
657
            unless ( m~/$implib$~ );
658
    }
659
    $pObjs = \@newobjs;
660
}
661
 
662
#
663
#   Extend the list of libraries with MOS specific libraries
664
#   This list may need multiple passes and will be replicated. Do not include
665
#   the compiler RTL library in this list as it will cause problems. It must be
666
#   linked last and linked only once.
667
#
668
    push( @$pLibs, 'glob' );
669
 
670
#   Create a list of system (RTL) libraries
671
#   We only want to use the compiler RTL library as a last resort and will only
672
#   make one pass over it.
673
#
674
    push( @$pSlibs, '$(mri_linker_lib)' );
675
 
676
#
677
#   Create a ABSRuleGenerator
678
#   This inherits from a a ToolsetPrinter and extends it to
679
#   allow addition data to be held
680
#
681
    my ($io) = ABSRuleGenerator::New( $name, $pObjs, $pLibs, $pSlibs );
682
 
683
 
684
########################################################################
685
#
686
#   Create a stub library to allow inter-module calls
687
#
688
if ( $implib )
689
{
690
    $io->Label( "Import(stub) library", $name );
691
    my $stub_lib = "\$(LIBDIR)/${name}\$(GBE_TYPE).${a}";
692
 
693
    #
694
    #   Rules and recipe to generate the stub library
695
    #
696
    #   If the implib was not named in the object list to this SharedLib
697
    #   then it will not be in OBJSOURCE and will not have a rule
698
    #
699
    #
700
    $::OBJSOURCE{"$name/$implib"} = $::OBJSOURCE{"$implib"}
701
        unless( $::OBJSOURCE{"$name/$implib"} );
702
    $io->Prt( "$stub_lib:\t\$(OBJDIR)/$name/$implib.$::o\n" );
703
    $io->Prt( "\t\$(AR)\n" );
704
    $io->Newline();
705
 
706
    #
707
    #   Files to be cleanup up
708
    #
709
    ToolsetGenerate( $stub_lib );
710
 
711
    #
712
    #   If the THX is being packaged/installed then add the static
713
    #   stub library to the packaging lists as a static library.
714
    #   This will allow the stub library to be installed with the
715
    #   static libraries and thus allow DLL's with mutual imports
716
    #
717
    PackageShlibAddLibFiles ($name, $stub_lib );
718
 
719
    #
720
    #   Add the stub library to the list of libraries being created
721
    #
722
    push @::LIBS, $name;
723
 
724
}
725
 
726
#
727
#   If we are only creating a sub library, then out work is done
728
#
729
if ( $stub_only )
730
{
731
    Error ("Request for stub library without specifying the Import file")
732
        unless ($implib);
733
    return;
734
}
735
 
736
########################################################################
737
#
738
#   Create the module header
739
#   This is a two step process
740
#       1) Create the head.inc file from the modules REL file
741
#       2) Compile the head.asm file
742
#
743
#   Note: "head.inc" is a fixed filename. It is created on demand
744
#         and left around
745
#
746
 
747
    $io->Label( "Module Header", $name );
748
    $io->Prt( "\$(OBJDIR)/${name}/head.$::o: $head_file $rel_file");
749
    $io->Prt( "\n\t\$(call AS_HEAD,$rel_file,$head_file,\$(OBJDIR)/${name}/head.$::o,\$(OBJDIR)/${name}/head.inc)\n" );
750
    $io->Newline();
751
 
752
    ToolsetObj     ( "\$(OBJDIR)/${name}/head" );
753
    ToolsetGenerate( "\$(OBJDIR)/${name}/head.inc" );
754
    ToolsetGenerate( "\$(OBJDIR)/head.inc" );
755
 
756
#
757
#   Create rules and recipes to generate two .abs files that are
758
#   used to generate relocation information
759
#
760
    $io->GenAbsFile( "OBJDIR", "_o", "S[3]", $module_type, "800000H", "100000H" );
761
    $io->GenAbsFile( "OBJDIR", "_0", "S[3]", $module_type, "400000H", "000000H" );
762
 
763
    #
764
    #   Create the relocation information from the two .abs files
765
    #   This file will be used to add to other abs files
766
    #
767
 
768
    $io->Prt( "\$(OBJDIR)/${name}_rtab_d.asm \$(OBJDIR)/${name}_rtab_cd.asm: BRTROOT=${name}\n" );
769
    $io->Entry( "\$(OBJDIR)/${name}_rtab_d.asm \$(OBJDIR)/${name}_rtab_cd.asm:\t", "", "\\\n\t\t\$(OBJDIR)/", ".abs ", ( "${name}_o", "${name}_0" ) );
770
    $io->Prt( "\n\t\$(BRT)\n" );
771
    $io->Newline();
772
 
773
    ToolsetGenerate( "\$(OBJDIR)/${name}_rtab_d.asm" );
774
    ToolsetGenerate( "\$(OBJDIR)/${name}_rtab_cd.asm" );
775
 
776
    #
777
    #   Rules to allow the two assembler files to be created
778
    #   Override user assembler flags to control the assembler environment
779
    #
780
    $io->Prt( "\$(OBJDIR)/${name}_rtab_d.$::o: ASFLAGS=-fNOPCR -frel32\n");
781
    $io->Prt( "\$(OBJDIR)/${name}_rtab_d.$::o: \$(OBJDIR)/${name}_rtab_d.asm");
782
    $io->Prt( "\n\t\$(AS)\n" );
783
    $io->Newline();
784
 
785
    $io->Prt( "\$(OBJDIR)/head.$::o: ASFLAGS=-fNOPCR -frel32\n");
786
    $io->Prt( "\$(OBJDIR)/${name}_rtab_cd.$::o: ASFLAGS=-fNOPCR -frel32\n");
787
    $io->Prt( "\$(OBJDIR)/${name}_rtab_cd.$::o: \$(OBJDIR)/${name}_rtab_cd.asm");
788
    $io->Prt( "\n\t\$(AS)\n" );
789
    $io->Newline();
790
 
791
    ToolsetObj( "\$(OBJDIR)/${name}_rtab_d" );
792
    ToolsetObj( "\$(OBJDIR)/${name}_rtab_cd" );
793
 
794
 
795
#
796
#   Create rules and recipes to generate the final .abs file which will feed into
797
#   the required .thx file. this file will now have embedded relocation information
798
#
799
    $io->GenAbsFile( "LIBDIR", "\$(GBE_TYPE)", "S[3]", $module_type, "400000H", "000000H", "\$(OBJDIR)/${name}_rtab_cd"  );
800
 
801
#
802
#   Create rules and recipes to generate a debug-able .abs file
803
#   This is a totally different beast and is then used to
804
#   create some debugger friendly files
805
#
806
    $io->GenAbsFile( "LIBDIR", "\$(GBE_TYPE)_debug", "IEEE", "debug", $debug_data, $debug_code, "\$(OBJDIR)/${name}_rtab_d" );
807
 
808
 
809
########################################################################
810
#
811
#   VisionClick support
812
#   Physivcal files will not be generated if the tool it not available
813
#   Either generate the files or provide phony targets
814
#
815
    $io->Label( "VisionClick support", $name );
816
    $io->Prt( "ifdef VISIONCLICK\n".
817
              "\$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt ".
818
              "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.bdx ".
819
              "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abx ".
820
              "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.ab: ".
821
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abs".
822
              "\n\t\t\$(call VCLICK, \$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abs,\\".
823
              "\n\t\t               \$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt,\\".
824
              "\n\t\t               \$(GBE_VCLICKDRV) )".
825
              "\nelse".
826
              "\n.PHONY:\t\$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt".
827
              "\n.PHONY:\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.bdx".
828
              "\n.PHONY:\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abx".
829
              "\n.PHONY:\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.ab".
830
              "\nendif\n\n" );
831
 
832
    #
833
    #   Vision Click files for cleanup
834
    #
835
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.bdx" );
836
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.ab" );
837
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abx" );
838
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abg" );
839
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt" );
840
 
841
    #
842
    #   Add the Visionclick files to the package lists
843
    #   These will only be packaged if VISIONCLICK is defined
844
    #
845
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.bdx" , 'defined=VISIONCLICK', 'Class=debug' );
846
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.ab"  , 'defined=VISIONCLICK', 'Class=debug' );
847
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abx" , 'defined=VISIONCLICK', 'Class=debug' );
848
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt", 'defined=VISIONCLICK', 'Class=debug' );
849
 
850
 
851
########################################################################
852
#
853
#   Rules and recipes to create the .THX (.BIN) file
854
#   This ties together all the previous components
855
#
856
#
857
    my $sh_ext = $bin_image ? 'bin' : $::so;
858
 
859
    $io->Label( "MOS Module", $name );
860
    $io->Prt( "\$(LIBDIR)/${name}\$(GBE_TYPE).$sh_ext :" .
861
              "\\\n\t\t\$(OBJDIR)/${name}_o.abs " .
862
              "\\\n\t\t\$(OBJDIR)/${name}_0.abs " .
863
              "\\\n\t\t\$(OBJDIR)/${name}_rtab_cd.asm " .
864
              "\\\n\t\t\$(OBJDIR)/${name}_rtab_d.asm " .
865
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE).abs " .
866
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abs " .
867
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_vpaths.txt ".
868
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.bdx ".
869
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abx ".
870
              "\\\n\t\t\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.ab "
871
            );
872
 
873
    if ( $bin_image)
874
    {
875
        $io->Prt( "\n\t\t\$(MODCRC_BIN)\n");
876
    }
877
    else
878
    {
879
        $io->Prt( "\n\t\t\$(MODCRC)\n");
880
    }
881
 
882
    #
883
    #   Register generated file for cleanup
884
    #   The MODCRC process generates a .bak file. Ensure that it gets removed
885
    #
886
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE).$sh_ext" );
887
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(GBE_TYPE).bak" );
888
 
889
    #
890
    #   Specify the files to be packaged as part of the shared library
891
    #
892
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE).$sh_ext" );
893
    PackageShlibAddFiles( $name, "\$(LIBDIR)/${name}\$(GBE_TYPE)_debug.abs", 'Class=debug' );
894
}
895
 
896
 
897
#-------------------------------------------------------------------------------
898
# package       : ABSRuleGenerator
899
#
900
# Description   : Package to contain data to generate rules to create
901
#                 ABS files.
902
#
903
#                 This is implemented as a class to allow blocks of
904
#                 data to be simply maintained
905
#
906
#                 This class ISA ToolsetPrinter too
907
#
908
# Parameters    : name      - Basic name of the library
909
#                 pObjs     - Ref to an array of object files to be linked
910
#                 pLibs     - Ref to an array of librarus to be linked
911
#                 pSlibs    - Ref to an array of system libraries to be linked
912
#                             These libraries will only be linked ONCE
913
#
914
package ABSRuleGenerator;
915
 
916
    use vars qw(@ISA);
917
    @ISA = ("ToolsetPrinter");
918
 
919
sub New
920
{
921
    my ($name, $pObjs, $pLibs, $pSlibs) = @_;
922
 
923
    my $self = ToolsetPrinter::New();
924
 
925
    $self->{name}  = $name;
926
    $self->{pObjs} = $pObjs;
927
    $self->{pLibs} = $pLibs;
928
    $self->{sLibs} = $pSlibs;
929
 
930
    return bless $self, __PACKAGE__;
931
}
932
 
933
#-------------------------------------------------------------------------------
934
# Function        : GenAbsFile
935
#
936
# Description     : Internal helper function to generate an ABS file
937
#                   with desirable characteristics
938
#
939
#                   Note: This function is not within the ToolsetSHLD to
940
#                         make closure problems obvious
941
#
942
# Inputs          : $1      - Name of the output directory (LIBDIR or OBJDIR)
943
#                   $2      - basename of the output file
944
#                   $3      - basename sufix
945
#                   $4      - Type of output IEEE /S[3]
946
#                   $5      - Kind of module - "acon", "data", "debug" or ""
947
#                   $6      - Base of the data segment
948
#                   $7      - Base of the code segment
949
#                   $8      - Extra (internal) object file to be linked in
950
#
951
# Returns         :
952
#
953
sub GenAbsFile
954
{
955
    my ( $io, $dir, $suf, $otype, $kind, $data_base, $code_base, $eObjs ) = @_;
956
    my $name  = $io->{'name'};
957
    my $pLibs = $io->{'pLibs'};
958
    my $pSlibs = $io->{'sLibs'};
959
 
960
    #
961
    #   Generate a full list of object files
962
    #
963
    my @allObjs = @{$io->{'pObjs'}};
964
    push @allObjs, $eObjs
965
        if ( $eObjs);
966
 
967
#
968
#.. Linker command file
969
#
970
#   Piecing together a variable $(name_ld) which ends up in the command file.
971
#   This bit of magic will be performed by the LDABS recipe
972
#
973
#
974
    $io->SetTag( "${name}${suf}_shld" );                  # macro tag
975
    $io->Label( "Linker commands", $name . $suf );      # label
976
 
977
    $io->Cmd("FORMAT      $otype" );
978
    $io->Cmd("CHIP	    \$(mri_cpu_type)" );
979
    $io->Cmd("LISTMAP     CROSSREF,INTERNALS,PUBLICS" );
980
 
981
    $io->Cmd("DEBUG_SYMBOLS" )        if ( $kind eq "debug" );
982
 
983
    unless ( $kind eq "acon" || $kind eq "data" )
984
    {
985
        $io->Cmd("MERGE vars  StartPixInit,pixinit,EndPixInit" );
986
        $io->Cmd("MERGE vars  StartInitFini,initfini,EndInitFini" );
987
        $io->Cmd("MERGE vars  cxx_rtti,cxx_edt" );
988
        $io->Cmd("INITDATA    vars" );
989
        $io->Cmd("INDEX       ?A5,zerovars" );
990
        $io->Cmd("EXTERN      __mosSoftTrap" );
991
    }
992
 
993
    if ( $kind eq "data" )
994
    {
995
        $io->Cmd("SECT        header = 0H" );
996
        $io->Cmd("ORDER       header,ascode,code,const" );
997
        $io->Cmd("ORDER       modtitle,lastsync" );
998
    }
999
    elsif ( $kind eq "acon" )
1000
    {
1001
        $io->Cmd("SECT        header = 0H" );
1002
        $io->Cmd("ORDER       header,const,code,ascode" );
1003
        $io->Cmd("ORDER       modtitle,lastsync" );
1004
    }
1005
    else
1006
    {
1007
        $io->Cmd("SECT        zerovars = $data_base" );
1008
        $io->Cmd("SECT        header = $code_base" );
1009
 
1010
        $io->Cmd("ORDER       zerovars,vars,uninivars" )      if ( $kind eq "debug" );
1011
        $io->Cmd("ORDER       header,ascode,code" );
1012
        $io->Cmd("ORDER       literals,strings,const" );
1013
        $io->Cmd("ORDER       ??INITDATA,modtitle,rellist,lastsync" );
1014
        $io->Cmd("ORDER       zerovars,vars,uninivars" )      unless ( $kind eq "debug" );
1015
        $io->Cmd("ORDER       stack" )                        if ( $kind eq "debug" );
1016
    }
1017
    $io->Cmd("ALIGN       lastsync,4" );
1018
    $io->Newline();
1019
 
1020
    #
1021
    #   Must load GLOB.LIB first so that "well-known" variables
1022
    #   in zerovars are at a known location
1023
    #
1024
    $io->Prt("#   Load the Global Library first\n");
1025
    $io->Newline();
1026
    $io->LibList( $name, ["glob"], \&ToolsetLibRecipe );
1027
    $io->Newline();
1028
 
1029
    $io->Prt("#   Load the module header and target specfic library\n");
1030
    $io->Prt("#\n");
1031
    $io->Cmd("LOAD    \$(OBJDIR)/${name}/head.$::o" );
1032
    $io->Newline();
1033
 
1034
    $io->Prt("#   List all the object files to be loaded\n");
1035
    $io->Prt("#\n");
1036
 
1037
    $io->ObjList( $name, \@allObjs, \&ToolsetObjRecipe );
1038
    $io->Newline();
1039
 
1040
    $io->Prt("#   Load the library files twice to overcome single pass linker problems\n");
1041
    $io->Prt("#\n");
1042
 
1043
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1044
    $io->Newline();
1045
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1046
    $io->Newline();
1047
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1048
    $io->Newline();
1049
 
1050
    $io->LibList( $name, $pSlibs, \&ToolsetLibRecipe );
1051
    $io->Newline();
1052
 
1053
    $io->Prt("#.. Map file options\n");
1054
    $io->Cmd("LISTMAP	LENGTH 64");
1055
    $io->Cmd("LISTMAP	CROSSREF,INTERNALS,PUBLICS/by_addr");
1056
    $io->Cmd("END");
1057
    $io->Newline();
1058
 
1059
 
1060
    #
1061
    #   Create the rules and recipes to create the required file
1062
    #
1063
    $io->Prt( "\$($dir)/${name}${suf}.abs:\tSHBASE=${name}${suf}\n" );
1064
    $io->Prt( "\$($dir)/${name}${suf}.abs:\tSHNAME=${name}${suf}\n" );
1065
    $io->Entry( "\$($dir)/${name}${suf}.abs :\t", "", "\\\n\t\t", ".$::o ", @allObjs );
1066
    $io->Prt( "\\\n\t\t\$(GBE_PLATFORM).mk " );
1067
    $io->Prt( "\\\n\t\t\$($dir)/${name}${suf}.dep " );
1068
    $io->Prt( "\\\n\t\t\$(OBJDIR)/${name}/head.$::o " );
1069
    $io->Prt( "\n\t\$(SHLDABS)\n" );
1070
    $io->Newline();
1071
 
1072
 
1073
    #.. Dependency link,
1074
    #
1075
    #       Now piece together a variable $(name_dp) which ends up in
1076
    #       the command file building the application dependency list.
1077
    #
1078
    $io->SetTag( "${name}${suf}_shdp" );                # macro tag
1079
    $io->DepRules( $name.$suf, $pLibs,                  # library depends rules
1080
            \&ToolsetLibRecipe, "\$($dir)/${name}${suf}.abs" );
1081
    $io->DepRules( $name.$suf, $pSlibs,                  # library depends rules
1082
            \&ToolsetLibRecipe, "\$($dir)/${name}${suf}.abs" );
1083
    $io->SHLDDEPEND( ${name}.${suf}, ${name}.${suf} ,${name}.${suf}, $dir );   # std LDDEPEND rules
1084
 
1085
#.. Cleanup rules
1086
#
1087
    ::ToolsetGenerate( "\$($dir)/${name}${suf}.ld" );
1088
    ::ToolsetGenerate( "\$($dir)/${name}${suf}.abs" );
1089
    ::ToolsetGenerate( "\$($dir)/${name}${suf}.map" );
1090
    ::ToolsetGenerate( "\$($dir)/${name}${suf}.dep" );
1091
 
1092
}
1093
 
1094
########################################################################
1095
#
1096
#   Generate a linker object recipe.  This is a helper function used 
1097
#   within this toolset.
1098
#
1099
#   Arguments:
1100
#       $io         I/O stream
1101
#
1102
#       $target     Name of the target
1103
#
1104
#       $obj        Library specification
1105
#
1106
########################################################################
1107
 
1108
sub ToolsetObjRecipe
1109
{
1110
    my ($io, $target, $obj) = @_;
1111
 
1112
    $io->Cmd("LOAD	$obj.$::o");
1113
}
1114
 
1115
########################################################################
1116
#
1117
#   Generate a linker/depend library recipe.  This is a helper function
1118
#   used within this toolset.
1119
#
1120
#   Arguments:
1121
#       $io         I/O stream
1122
#
1123
#       $target     Name of the target
1124
#
1125
#       $lib        Library specification
1126
#
1127
#       $dp         If building a depend list, the full target name.
1128
#
1129
########################################################################
1130
 
1131
sub ToolsetLibRecipe
1132
{
1133
    my ($io, $target, $lib, $dp) = @_;
1134
 
1135
    if ( !defined($dp) ) {                      # linker
1136
        $io->Cmd("LOAD	@(vpath2,$lib.$::a,MRI_LIB)" );
1137
 
1138
    } else {                                    # depend
1139
        $io->Cmd( "$dp:\t@(vlib2,$lib.$::a,MRI_LIB)" );
1140
    }
1141
}
1142
 
1143
package main;
1144
 
1145
###############################################################################
1146
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
1147
#       This subroutine takes the user options and builds the rules
1148
#       required to lint the program 'name'.
1149
#
1150
#   Arguments:
1151
#       (none)
1152
#
1153
#   Output:
1154
#       [ $(LIBDIR)/$name_lint:   .... ]
1155
#           $(SHLIBLINT)
1156
#
1157
###############################################################################
1158
 
1159
sub ToolsetSHLDLINT
1160
{
1161
    PCLintSHLIB( @_ );
1162
}
1163
 
1164
 
1165
#.. Successful termination
1166
1;
1167