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