Subversion Repositories DevTools

Rev

Rev 227 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

# -*- mode: perl; tabs: 8; indent-width: 4; show-tabs: yes; -*-
#
# Module name   : mri68k
# Module type   : Makefile system
# Compiler(s)   : ANSI C
# Environment(s): AMX/EOS
#
#                       ! WARNING - do not detab !
#
# Description:
#       MRI 68k toolset
#
# Version   Who      Date        Description
# 1.0       APY      07/05/99    Created
# 1.3       APY      06/12/99    NetTcp/NetUdp linker options
#                    09/12/99    ToolsetProg()
# 1.5                06/01/00    Linker --Kdb support
#                    07/01/00    ifeq "$(IFLAG)" "3"
#                                  around -include directives
#                    14/03/99    vpath2() for remove abs depend issues
#                    15/03/00    Wasn't build dependency list for binaries.
# 1.9       APY      16/03/00    --Section switch
# 1.10      APY      06/04/00    MRI version (4.4) support
#                    26/04/00    --NetTcpx
#           APY      13/11/00    ${exe} now embeddes '.' if required.
# 2.0       APY      26/02/02    Build system +v2 support.
#                                - reconstructed isp creation
#                                - replaced ToolsetProg() with ToolsetGenerate().
#                                - ToolsetCC and ToolsetCXX switch processing
#                    30/04/02    --Isp must allow multiple specifications.
#                    07/05/02    --Section
#
# $Name:  $
# $Source: /cvsroot/etm/devl/CFG/TOOLSET/MRI68K,v $
# $Revision: 1.3 $ $Date: 2004/09/03 10:25:23 $ $State: Exp $
# $Author: ayoung $ $Locker:  $
#............................................................................#

##############################################################################
#   ToolsetInit()
#       Runtime initialisation
#
##############################################################################

ToolsetInit();

$MriVersion                = "4.3";            # Compiler version

sub ToolsetInit
{
    my( @args ) = @ScmToolsetArgs;             # Toolset arguments

#.. Parse arguments
#
    Debug( "mri68k(@args)" );

    foreach $_ ( @args ) {
        if (/^--Version=(.*)/) {                # Compiler version
            $MriVersion = "$1";

        } else {                                # Unknown option
            Message( "mri68k: unknown option $_ -- ignored\n" );
        }
    }

#.. Standard.rul requirements
#
    $s   = 'asm';       # Assembler source file
    $o   = 'obj';       # Object file
    $a   = 'lib';       # Library file
    $exe = "";          # Dummy, real image is either 'abs' or 'bin'

#.. Define MRI environment
#
    Init( "mri", "mri2" );
    ToolsetDefine( "#################################################" );
    ToolsetDefine( "# MRI compiler version" );
    ToolsetDefine( "#" );
    ToolsetDefine( "mri_ver         = $MriVersion" );
    ToolsetDefine( "" );
    ToolsetDefine( "#" );
    ToolsetDefines( "mri68k.def" );
    ToolsetRules( "mri68k.rul" );
    ToolsetRules( "standard.rul" );
}

###############################################################################
#   ToolsetCC( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetCC
{
    my( $source, $obj, $pArgs ) = @_;

    Debug( "CC:  $source -> $obj" );
    foreach ( @$pArgs ) {
        Debug( "option:    $_" );
        if ( /--Shared$/ ) {                    # Building a 'shared' object
            $cflags = "$cflags \$(SHCFLAGS)";
            Debug( "CC:    as shared object" );
                
        } else {                                # unknown option
            Message( "CC: unknown option $_ -- ignored\n" );
        }               
    }   

    MakePrint( "\n\t\$(CC)\n" );
    MakePrint( "\$(OBJDIR)/$i.${o}:\tCFLAGS +=$cflags\n" )
        if ( $cflags );
}

###############################################################################
#   ToolsetCCDepend( $depend, \@sources )
#       This subroutine takes the user options and builds the
#       rule(s) required to build the dependencies for the source
#       files 'sources' to 'depend'.
#
###############################################################################

sub ToolsetCCDepend
{
    MakePrint( "\t\$(CCDEPEND)\n" );
}


###############################################################################
#   ToolsetCXX( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################
        
sub ToolsetCXX
{
    my( $source, $obj, $pArgs ) = @_;
    my( $cflags ) = "";

    Debug( "CCX: $source -> $obj" );
    foreach ( @$pArgs ) {
        Debug( "option:    $_" );
        if ( /--Shared$/ ) {                     # Building a 'shared' object
            $cflags = "$cflags \$(SHCXXFLAGS)";         
            Debug( "CCX:    as shared object" );
        
        } else {
            Message( "CCX: unknown option $_ -- ignored\n" );
        }               
    }   

    MakePrint( "\n\t\$(CXX)\n" );               
    MakePrint( "\$(OBJDIR)/$i.${o}:\tCXXFLAGS +=$cflags\n" )
        if ( $cflags );
}       


###############################################################################
#   ToolsetCXXDepend( $depend, \@sources )
#       This subroutine takes the user options and builds the
#       rule(s) required to build the dependencies for the source
#       files 'sources' to 'depend'.
#
###############################################################################

sub ToolsetCXXDepend
{
    #ToolsetCCDepend() handles both CC and CXX source
}


###############################################################################
#   ToolsetAS( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetAS
{
    my( $source, $obj, $pArgs ) = @_;

    foreach $_ ( @$pArgs ) {
        Message( "CC: unknown option $_ -- ignored\n" );
    }   

    MakePrint( "\n\t\$(AS)\n" );
}

sub ToolsetASDepend
{
}


###############################################################################
#   ToolsetAR( $name, \@args, \@objs )
#       This subroutine takes the user options and builds the rules
#       required to build the library 'name'.
#
#   Arguments:
#       --Amx[=prefix]          local AMX configuration (defaults to platform)
#       --Isp=name              ISP module
#       --[wlib|386lib]         Librarian (todo)
#
#   Output:
#       [ $(LIBDIR)/name$.${a}:   .... ]
#           $(AR)
#
###############################################################################

sub ToolsetAR
{
    my( $name, $pArgs, $pObjs ) = @_;
    my( $amx, @isp, $insight );

    local( $name_ld );

#.. Parse arguments
#
    $amx = $insight = 0;                        # options
    foreach $_ ( @$pArgs ) {
        if (/^--Amx$/) {                        # Local AMX config
            $amx     = "\$(SCM_PLATFORM)";
        } elsif (/^--Amx=(.*)/) {               # Specific AMX config
            $amx     = "$1";
        } elsif (/^--Isp=(.*)/) {               # ISP module
            push( @isp, "$1" );

        } elsif (/^--Insight$/) {               # Enable insight
            $insight = 1;
        } elsif (/^--Insight=(.*)/) {           # Specific insight
            $insight = "$1";

        } else {
            Message( "AR: unknown option $_ -- ignored\n" );
        }
    }

#.. Standard library builds, plus AMX configuration                             
#                       
    MakeEntry( "\$(LIBDIR)/$name\$(SCM_TYPE).${a}:\t",
                  "", "\\\n\t\t", ".${o} ", @$pObjs );

#.. Build library with AMX configuration
#
    foreach (@isp) {
        AmxLibISP( $name, $_ );
    }
    AmxLib( $name, $amx, $insight )
        if ( $amx );

#.. Build library rule (just append to standard rule)
#
    MakePrint( "\n\t\$(AR)\n\n" );
}


###############################################################################
#   ToolsetLD( $name, \@args, \@objs, \@libraries )
#       This subroutine takes the user options and builds the rules
#       required to link the program 'name'.
#
#   Arguments:
#       EOS specific:
#       --Eos                   EOS application
#       --Eosx                  Extended EOS application
#       --EosRom                EOS BOOTROM application
#       --EosRomx               Extended EOS BOOTROM application
#       --NetUdp[P]             Networking with UDP support
#       --NetTcp[P]             Networking with TCP support (static routing)
#       --NetTcpx[P]            Networking with TCP support (router)
#       --Kdb                   Kernel debugger
#
#       AMX specific:
#       --Amx[=prefix]          Local AMX configuration (defaults to platform)
#       --Isp=name              ISP module
#       --Insight[=prefix]      Enable insight (default to platform.icf)
#                               (incomplete)
#
#       Linker specific:
#       --Bin=LoadAddr          Download image
#       --Abs                   Absoluate image (Powerscope/VisionClick)
#       --Section=...           Linker sector order directives
#
#   Output:                     (also mri68k.rul)
#
#       $(BINDIR)/name${exe}:
#                       $(BINDIR)/name.dep \
#                       $(BINDIR)/name.[abs|bin]
#
#       .PHONY:                 $(BINDIR)/name${exe}:
#
#       $(BINDIR)/name.dep:     $(SCM_PLATFORM).mk
#               $(LDDEPEND)
#
#       ifeq "$(IFLAG)" "3"
#       -include        "$(BINDIR)/name.dep"
#       endif
#
#       $(BINDIR)/name.[abs|bin]
#                       objs ...
#               {$(LDABS)|$(LDBIN)}
#
#       name_ld += ...  Linker command file
#           :
#
#       name_dp += ...  Dependency list
#           :
#
###############################################################################

sub ToolsetLD
{
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
    my( $linker, $flags, $amx, $insight );
    my( $laddr, $lsize, $section );
    my( $cond );
    local( $varname );

#.. Parse arguments
#
    $amx = $flags = $insight = 0;               # generic options
    $section = ""; $laddr = 0;                  # toolset options

    foreach $_ ( @$pArgs )
    {
    #.. EOS
    #
        if (/--Eos$/) {                         # EOS standard
            $flags     = $flags | $EOS_LNK;
        } elsif (/^--Eosx$/) {                  # EOS extended
            $flags     = $flags | $EOS_LNK | $EOS_EXT;
        } elsif (/^--EosRom$/) {                # ROM image
            $flags     = $flags | $EOS_LNK | $EOS_ROM;
        } elsif (/^--EosRomx$/) {               # ROM image extended
            $flags     = $flags | $EOS_LNK | $EOS_ROM | $EOS_EXT;

        } elsif (/^--NetUdp$/) {
            $flags     = $flags | $NET_UDP;
        } elsif (/^--NetTcp$/) {                # TCP with static router
            $flags     = $flags | $NET_TCP;
        } elsif (/^--NetTcpx$/) {               # TCP with router
            $flags     = $flags | $NET_TCP | $NET_ROUTER;

        } elsif (/^--NetUdpP$/) {
            $flags     = $flags | $NET_UDP | $NET_PROD;
        } elsif (/^--NetTcpP$/) {               # TCP with static router
            $flags     = $flags | $NET_TCP | $NET_PROD;
        } elsif (/^--NetTcpxP$/) {              # TCP with router
            $flags     = $flags | $NET_TCP | $NET_ROUTER | $NET_PROD;

        } elsif (/^--Kdb/) {                    # Kernel debugger
            $flags = $flags | $EOS_KDB;

    #.. AMX
    #
        } elsif (/^--Amx$/) {                   # Local AMX config
            $amx     = "\$(SCM_PLATFORM)";
        } elsif (/^--Amx=(.*)/) {               # Specific AMX config
            $amx     = "$1";

        } elsif (/^--Isp=(.*)/) {               # ISP module
            if ( ! $flags && ! $amx ) {
                Message( "LD: --Isp requires either a EOS or AMX application");
            } else {
                AmxLinkISP( $name, "$1", $pObjs, $pLibs );
            }

        } elsif (/^--Insight$/) {               # Enable insight
            $insight = "\$(SCM_PLATFORM)";
        } elsif (/^--Insight=(.*)/) {           # Specific insight
            $insight = "$1";

    #.. Target specific
    #
        } elsif (/^--Abs/) {                    # Absolute image
            $lsize = $lsize = "";

        } elsif (/^--Bin$/) {                   # Binary 'S-Record' image
            $flags = $flags | $EOS_BIN;
            $laddr = "0";                       # Load address

        } elsif (/^--Bin=(.*)/) {               # Download image
            $flags = $flags | $EOS_BIN;
            $laddr = "$1";                      # Load address

        } elsif (/^--Bin=(.*),(.*)/) {          # Download image
            $flags = $flags | $EOS_BIN;
            $laddr = "$1";                      # Load address
            $lsize = "$2";                      # Image size

        } elsif (/^--Section=(.*)/) {           # Section directives
            $section = "$1";

    #.. Toolset specific
    #
        } else {
            Message( "LD: unknown option $_ -- ignored\n" );
        }
    }

#.. Command file, EOS and/or AMX dependencies
#
#   Library search order,
#       Application
#       EOS
#       AMX
#       Toolset
#
    if ( $flags & $EOS_LNK ) {
        EosLink( $name, $flags, $pObjs, $pLibs );
        if ( $amx ) {
            AmxLinkCfg( $name, $amx, $insight, $pObjs, $pLibs );
        } else {
            AmxLinkStd( $name, $pObjs, $pLibs );
        }
    } elsif ( $amx ) {
        AmxLinkCfg( $name, $amx, $insight, $pObjs, $pLibs );
    }
    push( @$pLibs, "\$(mri)/68020/mcc68kab" );

#.. Link rules
#
if ($flags & $EOS_BIN) 
{
    MakePrint( "\\\n\t\t\$(BINDIR)/${name}.dep " .
               "\\\n\t\t\$(BINDIR)/${name}.bin\n\n" .
               ".PHONY:\t\t\t\$(BINDIR)/${name}${exe}\n\n" );

    MakePrint( "\$(BINDIR)/${name}.dep:\t\$(SCM_PLATFORM).mk\n".
                    "\t\$(LDDEPEND)\n\n" );

    MakePrint( "ifeq \"\$(IFLAG)\" \"3\"\n" .
               "-include\t\$(BINDIR)/${name}.dep\n" .
               "endif\n\n" );

    MakePrint( "\$(BINDIR)/${name}.bin:\tLADDR=$laddr\n" )
        if ( $laddr );
    MakePrint( "\$(BINDIR)/${name}.bin:\tLSIZE=$lsize\n" )
        if ( $lsize );

    MakePrint( "\$(BINDIR)/${name}.bin:" );
    foreach $i ( @$pObjs ) {
        MakePrint( " \\\n\t\t$i.${o}" );
    }
    MakePrint( "\n\t\$(LDBIN)\n" );
}
else
{
    MakePrint( "\\\n\t\t\$(BINDIR)/${name}.dep " .
               "\\\n\t\t\$(BINDIR)/${name}.abs\n\n" .
               ".PHONY:\t\t\t\$(BINDIR)/${name}${exe}\n\n" );

    MakePrint( "\$(BINDIR)/${name}.dep:\t\$(SCM_PLATFORM).mk\n".
                    "\t\$(LDDEPEND)\n\n" );

    MakePrint( "ifeq \"\$(IFLAG)\" \"3\"\n" .
               "-include\t\$(BINDIR)/${name}.dep\n" .
               "endif\n\n" );

    MakePrint( "\$(BINDIR)/${name}.abs:" );
    foreach $i ( @$pObjs ) {
        MakePrint( " \\\n\t\t$i.${o}" );
    }
    MakePrint( "\n\t\$(LDABS)\n" );
}
    MakePrint( "\n" );

#.. Cleanup rules
#
    ToolsetGenerate( "\$(BINDIR)/${name}.ld" );
    ToolsetGenerate( "\$(BINDIR)/${name}.dep" );
if ($laddr) {
    ToolsetGenerate( "\$(BINDIR)/${name}.bin" );
} else {
    ToolsetGenerate( "\$(BINDIR)/${name}.abs" );
}
    ToolsetGenerate( "\$(BINDIR)/${name}.map" );

#.. Linker command file
#
#       Now the fun part... piecing together a variable $(name_ld)
#       which ends up in the command file.
#
    $varname = "${name}_ld";
    sub VarCmd {
        MakeQuote ("$varname += @_\\n\n");
    }
    sub VarPrt {
        MakePrint ("@_\n");
    }

       VarCmd("CASE");                          #preserve symbols case
       VarCmd("WARN     356");                  #warning for undef sections
       VarCmd("CHIP     CPU32");                #68xxx (68332/68340/68341)
       VarCmd("INITDATA vars");                 #initialise 'vars' section

   if ($section) {
       VarPrt("#.. User specified section directives");
       VarCmd("$section");

   } else {
    if (($flags & $EOS_LNK) || $amx) {

     if ($flags & $EOS_ROM) {                   #BOOTROM
      if ($flags & $EOS_BIN) {
       VarPrt("#.. Linking an EOS-AMX/ROM image (Binary image)");
      } else {
       VarPrt("#.. Linking an EOS-AMX/ROM image (Powerscope image)");
      }

       VarCmd("extern   _BootVectors");         #create an external reference
       VarCmd("alias    code CODE");            #CODE alias
       VarCmd("align    vectors 4");            #align on quad boundaries
       VarCmd("align    ramVectors 4");         #..
       VarCmd("align    header 4");             #..
       VarCmd("align    (CODE)=4");             #..
       VarCmd("align    (DATA)=4");             #..
       VarCmd("align    (ROMDATA)=4");          #..

      if ($flags & $EOS_ROM) {
       VarCmd("order    SysRom");               #boot ROM/flash
      } else {
       VarCmd("order    SysRam");
      }
       VarCmd("order    vectors,header,startup,code");
       VarCmd("order    const,literals,strings,??INITDATA");

      if ($flags & $EOS_ROM) {
       # Note:  Shall generate a order warning if the ROM load address
       #        is NOT positioned at $0.
       #
       # eg.    "(374) ORDER command could not be obeyed for section SysRam."
       #..
       VarCmd("order    SysRam,PLoadEnv");      #program loader RAM
      }

       VarCmd("order    preserve,protected,ramVectors");
       VarCmd("order    vars,zerovars");        #MRI specific
       VarCmd("order    ioports,tags");         #..
       VarCmd("order    0")                     #..
          if ($MriVersion ne "4.4");

       VarCmd("order    BootStack,BootData");

     } else {                                   #application
      if ($flags & $EOS_BIN) {
       VarPrt("#.. Linking an EOS-AMX/Application image (Binary image)");
      } else {
       VarPrt("#.. Linking an EOS-AMX/Application image (Powerscope image)");
      }

       VarCmd("extern   _AsReset");             #create an external reference
       VarCmd("alias    code CODE");            #CODE alias
       VarCmd("align    vectors 4");            #align on quad boundaries
       VarCmd("align    ramVectors 4");         #..
       VarCmd("align    header 4");             #..
       VarCmd("align    (CODE)=4");             #..
       VarCmd("align    (DATA)=4");             #..
       VarCmd("align    (ROMDATA)=4");          #..
       VarCmd("order    SysRam");               #define sections to go into RAM
                                                #EOS/AS (start of RAM)
       VarCmd("order    preserve,protected,ramVectors");
       VarCmd("order    vars,zerovars");        #MRI specific
       VarCmd("order    ioports,tags");         #..
       VarCmd("order    0")                     #..
          if ($MriVersion ne "4.4");
       VarCmd("order    stack");                #application stack

       if ($flags & $EOS_BIN) {
        VarCmd("order   SysFlash");             #code image into FLASH
       }

       VarCmd("order    header,vectors");       #EOS/AS (start of FLASH)
       VarCmd("order    startup,code");         #..
       VarCmd("order    const");                #constant data sections
       VarCmd("order    literals");
       VarCmd("order    strings");
       VarCmd("order    ??INITDATA");           #data to copy into RAM
     }
    } else {
       VarPrt("#.. Link a generic 68k image");
       VarCmd("sect     vectors  0000");
       VarCmd("sectsize vectors= 1024");
       VarCmd("common   stack=   1024");
       VarCmd("sectsize stack=   4096");
       VarCmd("order    vectors,stack,code");
       VarCmd("order    literals,strings,const");
       VarCmd("order    ??INITDATA,vars,zerovars");
    }
}

        VarPrt("#.. The following are cmdfile macros, with libraries");
        VarPrt("#   repeated due to single pass linker wierdness");
    foreach $i ( @$pObjs ) {
        VarCmd("LOAD    @(dosify,$i.${o})" );
    }

                                                # Libraries
    $cond = "";
    foreach $_ ( @$pLibs ) {
        if (/^--ifdef=(.*)/) {                  # .. conditionals
            $cond = "$1";
            VarPrt( "ifdef $cond" );
            next;
        } elsif (/^--ifndef=(.*)/) {
            $cond = "$1";
            VarPrt( "ifndef $cond" );
            next;
        } elsif (/^--*/) {                      # .. unknown
            Message( "LD: unknown lib option $_ -- ignored\n" );
            next;
        }
                                                # .. entry
        VarCmd("LOAD    @(dosify,@(vpath2,$_.${a},MRI_LIB))" );

        if ($cond) {                            # .. end condition
            VarPrt("endif\t# $cond");
            $cond = "";
        }
    }

                                                # single pass linker wierdness
    foreach $_ ( @$pLibs ) {
        if (/^--ifdef=(.*)/) {                  # .. conditionals
            $cond = "$1";
            VarPrt( "ifdef $cond" );
            next;
        } elsif (/^--ifndef=(.*)/) {
            $cond = "$1";
            VarPrt( "ifndef $cond" );
            next;
        } elsif (/^--*/) {                      # .. unknown (warning only once)
            next;
        }
                                                # .. entry
        VarCmd("LOAD    @(dosify,@(vpath2,$_.${a},MRI_LIB))" );

        if ($cond) {                            # .. end condition
            VarPrt("endif\t# $cond");
            $cond = "";
        }
    }


        VarPrt("#.. Map file options");
        VarCmd("LISTABS INTERNALS, PUBLICS");
        VarCmd("LISTMAP LENGTH 64");            # map file page length");
        VarCmd("LISTMAP CROSSREF,INTERNALS,PUBLICS/by_addr");
        VarCmd("DEBUG_SYMBOLS");
        VarCmd("END");
        VarPrt( "" );

#.. Dependency link,
#
#       Now piece together a variable $(name_dp) which ends up in
#       the command file building the application dependency list.
#
    $varname = "${name}_dp";

    $cond = "";
    foreach $_ ( @$pLibs ) {
        if (/^--ifdef=(.*)/) {               # .. conditionals
            $cond = "$1";
            VarPrt( "ifdef $cond\n" );
            next;
        } elsif (/^--ifndef=(.*)/) {
            $cond = "$1";
            VarPrt( "ifndef $cond\n" );
            next;
        } elsif (/^--*/) {                   # .. unknown (warning only once)
            next;
        }
                                             # .. entry
        if ($laddr) {
             VarCmd("\$(BINDIR)/${name}.bin:    @(vpath2,$_.${a},MRI_LIB)" );
        } else {
             VarCmd("\$(BINDIR)/${name}.abs:    @(vpath2,$_.${a},MRI_LIB)" );
        }

        if ($cond) {                         # .. end condition
            VarPrt("endif\t# $cond\n");
            $cond = "";
        }
    }

#end ...
}

#.. Successful termination
1;