]> git.sur5r.net Git - cc65/commitdiff
Created C1P object file generator.
authorStephan Mühlstrasser <stephan.muehlstrasser@web.de>
Tue, 16 Jul 2013 20:29:14 +0000 (22:29 +0200)
committerStephan Mühlstrasser <stephan.muehlstrasser@web.de>
Tue, 16 Jul 2013 20:31:10 +0000 (22:31 +0200)
src/Makefile
src/c1p65.vcxproj [new file with mode: 0644]
src/c1p65/main.c [new file with mode: 0644]

index 3d046314735728105a9d860eccabf63d49755971..4a80a78fbc553163d089fab8ef6dc08b3181d7ee 100644 (file)
@@ -1,6 +1,7 @@
 ifeq ($(shell echo),)
 
 PROGS = ar65  \
+        c1p65 \
         ca65  \
         cc65  \
         cl65  \
diff --git a/src/c1p65.vcxproj b/src/c1p65.vcxproj
new file mode 100644 (file)
index 0000000..2f4ff02
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="c1p65\main.c" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{4E031DE0-82B4-4204-8529-536626F7E0DF}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>c1p65</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>
+    </CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>
+    </CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\bin\</OutDir>
+    <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\bin\</OutDir>
+    <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/c1p65/main.c b/src/c1p65/main.c
new file mode 100644 (file)
index 0000000..c15c77a
--- /dev/null
@@ -0,0 +1,219 @@
+/* Object file conversion utility for Challenger 1P
+
+   by Stephan Muehlstrasser
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+/* common stuff */
+#include "abend.h"
+#include "cmdline.h"
+#include "fname.h"
+#include "chartype.h"
+#include "target.h"
+#include "version.h"
+#include "xmalloc.h"
+
+static void Usage (void)
+{
+    printf (
+        "Usage: %s [options] file\n"
+        "Short options:\n"
+        "  -V\t\t\tPrint the version number\n"
+        "  -h\t\t\tHelp (this text)\n"
+               "  -o name\t\tName the C1P output file (default: <input.c1p>)\n"
+               "  -S addr\t\tLoad address (default 0x400)\n"
+        "\n"
+        "Long options:\n"
+        "  --help\t\tHelp (this text)\n"
+        "  --version\t\tPrint the version number\n",
+        ProgName);
+}
+
+static void OptHelp (const char* Opt attribute ((unused)),
+                     const char* Arg attribute ((unused)))
+/* Print usage information and exit */
+{
+    Usage ();
+    exit (EXIT_SUCCESS);
+}
+
+
+static void OptVersion (const char* Opt attribute ((unused)),
+                        const char* Arg attribute ((unused)))
+/* Print the program version */
+{
+    fprintf (stderr, "grc65 V%s\n", GetVersionAsString ());
+}
+
+
+static unsigned long CvtNumber (const char* Arg, const char* Number)
+/* Convert a number from a string. Allow '$' and '0x' prefixes for hex
+ * numbers. Duplicated from ld65's main.c.
+ */
+{
+    unsigned long Val;
+    int           Converted;
+
+    /* Convert */
+    if (*Number == '$') {
+        ++Number;
+        Converted = sscanf (Number, "%lx", &Val);
+    } else {
+        Converted = sscanf (Number, "%li", (long*)&Val);
+    }
+
+    /* Check if we do really have a number */
+    if (Converted != 1) {
+        AbEnd ("Invalid number given in argument: %s\n", Arg);
+    }
+
+    /* Return the result */
+    return Val;
+}
+
+/* Commands of C1P PROM monitor */
+#define ADDRESS_MODE_CMD     '.'
+#define DATA_MODE_CMD        '/'
+#define EXECUTE_CMD          'G'
+
+/* Transform the cc65 executable binary into a series of
+   commands that make the C1P PROM monitor load the bytes
+   into memory.
+*/
+static void Transform (unsigned long StartAddress, FILE *In, FILE *Out)
+{
+       int c;
+       unsigned long CurrentAddress;
+
+       /* Loop over all input bytes, position to current address,
+          switch to data mod, output input byte
+       */
+       for (CurrentAddress = StartAddress, c = getc(In);
+                               c != EOF;
+                               c = getc(In), CurrentAddress += 1) {
+               fprintf (Out, "%c%04.4X%c%02.2X",
+                       ADDRESS_MODE_CMD, (unsigned int) CurrentAddress & 0xFFFF,
+                       DATA_MODE_CMD, (unsigned int) c & 0xFF);
+       }
+
+       /* And execute
+       fprintf (Out, "%c%04.4x%c",
+                       ADDRESS_MODE_CMD, (unsigned int) StartAddress & 0xFFFF,
+                       EXECUTE_CMD);
+                        */
+} 
+
+/* Default suffix for C1P object file */
+#define C1P_SUFFIX ".c1p"
+
+int main (int argc, char *argv[])
+{
+    /* Program long options */
+    static const LongOpt OptTab[] = {
+        { "--help",    0, OptHelp},
+        { "--version", 0, OptVersion},
+    };
+
+       /* Initialize input and output file name */
+    const char* InputFile = 0;
+    const char* OutputFile = 0;
+       char *GeneratedOutputFile = 0;
+
+       /* Initialize file pointers */
+       FILE *InputFileFp = 0;
+       FILE *OutputFileFp = 0;
+
+       /* Initialize with default start address defined in c1p.cfg */
+       unsigned long StartAddr = 0x400;
+
+    unsigned int I;
+
+    /* Initialize the cmdline module */
+    InitCmdLine (&argc, &argv, "c1p65");
+
+    /* Check the parameters */
+    I = 1;
+    while (I < ArgCount) {
+
+        /* Get the argument */
+        const char* Arg = ArgVec [I];
+
+        /* Check for an option */
+        if (Arg[0] == '-') {
+            switch (Arg[1]) {
+
+                case '-':
+                    LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
+                    break;
+
+                case 'o':
+                    OutputFile = GetArg (&I, 2);
+                    break;
+
+                case 'S':
+                    StartAddr = CvtNumber (Arg, GetArg (&I, 2));
+                    break;
+
+                case 'h':
+                case '?':
+                    OptHelp (Arg, 0);
+                    break;
+
+                case 'V':
+                    OptVersion (Arg, 0);
+                    break;
+
+                default:
+                    UnknownOption (Arg);
+            }
+
+        } else {
+            if (InputFile) {
+                fprintf (stderr, "additional file specs ignored\n");
+            } else {
+                InputFile = Arg;
+            }
+        }
+
+        /* Next argument */
+        ++I;
+    }
+
+    if (!InputFile) AbEnd ("No input file");
+
+       if (!OutputFile) {
+               const size_t len = strlen(InputFile) + sizeof(C1P_SUFFIX);
+               
+               GeneratedOutputFile = (char *) xmalloc(len);
+               sprintf(GeneratedOutputFile, "%s%s", InputFile, C1P_SUFFIX);
+               OutputFile = GeneratedOutputFile;
+       }
+
+       /* Open input and output files */
+       InputFileFp = fopen(InputFile, "rb");
+       if (!InputFileFp) AbEnd ("Unable to open input file");
+
+       OutputFileFp = fopen(OutputFile, "wb");
+       if (!OutputFileFp) AbEnd ("Unable to open output file");
+
+       /* Generate object file */
+       Transform (StartAddr, InputFileFp, OutputFileFp);
+
+       /* Cleanup */
+       if (fclose(InputFileFp) == EOF) AbEnd ("Error closing input file");
+
+       if (fclose(OutputFileFp) == EOF) AbEnd ("Error closing output file");
+
+       if (GeneratedOutputFile) {
+               xfree(GeneratedOutputFile);
+       }
+
+    return EXIT_SUCCESS;
+}