]> git.sur5r.net Git - cc65/commitdiff
Renamed chrcvt to chrcvt65 and added it to the build.
authorOliver Schmidt <ol.sc@web.de>
Sun, 27 Mar 2016 17:09:00 +0000 (19:09 +0200)
committerOliver Schmidt <ol.sc@web.de>
Sun, 27 Mar 2016 17:09:00 +0000 (19:09 +0200)
The /Makefile presumes that all binaries are are named *65 so chrcvt had to be renamed in order to be added to the build.

doc/chrcvt.sgml [deleted file]
doc/chrcvt65.sgml [new file with mode: 0644]
doc/index.sgml
src/Makefile
src/chrcvt/error.c [deleted file]
src/chrcvt/error.h [deleted file]
src/chrcvt/main.c [deleted file]
src/chrcvt65/error.c [new file with mode: 0644]
src/chrcvt65/error.h [new file with mode: 0644]
src/chrcvt65/main.c [new file with mode: 0644]

diff --git a/doc/chrcvt.sgml b/doc/chrcvt.sgml
deleted file mode 100644 (file)
index 848fb52..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-<!doctype linuxdoc system>      <!-- -*- text-mode -*- -->
-
-<article>
-<title>chrcvt Users Guide
-<author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal">
-<date>2013-02-10
-
-<abstract>
-chrcvt is the vector font converter. It is able to convert a foreign font into
-the native format.
-</abstract>
-
-<!-- Table of contents -->
-<toc>
-
-<!-- Begin the document -->
-
-
-<sect>Overview<p>
-
-chrcvt is a vector font converter. It is able to convert a "BGI Stroked
-Font" to a compact TGI native vector font. See the function <url
-url="funcref.html#tgi_load_vectorfont" name="tgi_load_vectorfont"> for usage.
-
-
-
-<sect>Usage<p>
-
-The chrcvt utility converts the font of one Borland file to its cc65 equivalent.
-
-
-<sect1>Command line option overview<p>
-
-The program may be called as follows:
-
-<tscreen><verb>
----------------------------------------------------------------------------
-Usage: chrcvt [options] file [options] [file]
-Short options:
-  -h                    Help (this text)
-  -v                    Be more verbose
-  -V                    Print the version number and exit
-
-Long options:
-  --help                Help (this text)
-  --verbose             Be more verbose
-  --version             Print the version number and exit
----------------------------------------------------------------------------
-</verb></tscreen>
-
-
-<sect1>Command line options in detail<p>
-
-Here is a description of all the command line options:
-
-<descrip>
-
-  <tag><tt>-v, --verbose</tt></tag>
-
-  Increase the converter verbosity.
-
-
-  <tag><tt>-h, --help</tt></tag>
-
-  Print the short option summary shown above.
-
-
-  <tag><tt>-V, --version</tt></tag>
-
-  Print the version number of the utility. When submitting a bug report,
-  please include the operating system you're using, and the compiler
-  version.
-</descrip>
-
-
-<sect>Input and output<p>
-
-The converter will read one CHR file per invocation and write the font
-in TCH format to a new file.
-
-Example output for the command
-<tscreen><verb>
-chrcvt --verbose LITT.CHR
-</verb></tscreen>
-<tscreen><verb>
-BGI Stroked Font V1.1 - Aug 12, 1991
-Copyright (c) 1987,1988 Borland International
-</verb></tscreen>
-
-
-
-<sect>Copyright<p>
-
-chrcvt is (C) Copyright 2009, Ullrich von Bassewitz. For usage of the
-binaries and/or sources the following conditions apply:
-
-This software is provided 'as-is', without any expressed or implied
-warranty.  In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-<enum>
-<item> The origin of this software must not be misrepresented; you must not
-       claim that you wrote the original software. If you use this software
-       in a product, an acknowledgment in the product documentation would be
-       appreciated but is not required.
-<item> Altered source versions must be plainly marked as such, and must not
-       be misrepresented as being the original software.
-<item> This notice may not be removed or altered from any source
-       distribution.
-</enum>
-
-</article>
diff --git a/doc/chrcvt65.sgml b/doc/chrcvt65.sgml
new file mode 100644 (file)
index 0000000..0c55384
--- /dev/null
@@ -0,0 +1,116 @@
+<!doctype linuxdoc system>      <!-- -*- text-mode -*- -->
+
+<article>
+<title>chrcvt65 Users Guide
+<author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal">
+<date>2013-02-10
+
+<abstract>
+chrcvt65 is the vector font converter. It is able to convert a foreign font into
+the native format.
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+
+<sect>Overview<p>
+
+chrcvt65 is a vector font converter. It is able to convert a "BGI Stroked
+Font" to a compact TGI native vector font. See the function <url
+url="funcref.html#tgi_load_vectorfont" name="tgi_load_vectorfont"> for usage.
+
+
+
+<sect>Usage<p>
+
+The chrcvt65 utility converts the font of one Borland file to its cc65 equivalent.
+
+
+<sect1>Command line option overview<p>
+
+The program may be called as follows:
+
+<tscreen><verb>
+---------------------------------------------------------------------------
+Usage: chrcvt65 [options] file [options] [file]
+Short options:
+  -h                    Help (this text)
+  -v                    Be more verbose
+  -V                    Print the version number and exit
+
+Long options:
+  --help                Help (this text)
+  --verbose             Be more verbose
+  --version             Print the version number and exit
+---------------------------------------------------------------------------
+</verb></tscreen>
+
+
+<sect1>Command line options in detail<p>
+
+Here is a description of all the command line options:
+
+<descrip>
+
+  <tag><tt>-v, --verbose</tt></tag>
+
+  Increase the converter verbosity.
+
+
+  <tag><tt>-h, --help</tt></tag>
+
+  Print the short option summary shown above.
+
+
+  <tag><tt>-V, --version</tt></tag>
+
+  Print the version number of the utility. When submitting a bug report,
+  please include the operating system you're using, and the compiler
+  version.
+</descrip>
+
+
+<sect>Input and output<p>
+
+The converter will read one CHR file per invocation and write the font
+in TCH format to a new file.
+
+Example output for the command
+<tscreen><verb>
+chrcvt65 --verbose LITT.CHR
+</verb></tscreen>
+<tscreen><verb>
+BGI Stroked Font V1.1 - Aug 12, 1991
+Copyright (c) 1987,1988 Borland International
+</verb></tscreen>
+
+
+
+<sect>Copyright<p>
+
+chrcvt65 is (C) Copyright 2009, Ullrich von Bassewitz. For usage of the
+binaries and/or sources the following conditions apply:
+
+This software is provided 'as-is', without any expressed or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+<enum>
+<item> The origin of this software must not be misrepresented; you must not
+       claim that you wrote the original software. If you use this software
+       in a product, an acknowledgment in the product documentation would be
+       appreciated but is not required.
+<item> Altered source versions must be plainly marked as such, and must not
+       be misrepresented as being the original software.
+<item> This notice may not be removed or altered from any source
+       distribution.
+</enum>
+
+</article>
index 68f755a29d32e6d7e4e06ef2dce48bb76c5adb56..44b58ef5e62af7785bdff32b8551d710744abcc1 100644 (file)
@@ -18,7 +18,7 @@
   <tag><htmlurl url="cc65.html" name="cc65.html"></tag>
   Describes the cc65 C compiler.
 
-  <tag><htmlurl url="chrcvt.html" name="chrcvt.html"></tag>
+  <tag><htmlurl url="chrcvt65.html" name="chrcvt65.html"></tag>
   Describes the vector font converter.
 
   <tag><htmlurl url="cl65.html" name="cl65.html"></tag>
@@ -31,7 +31,7 @@
   Describes the da65 6502/65C02 disassembler.
 
   <tag><htmlurl url="grc65.html" name="grc65.html"></tag>
-  Describes the GEOS resource compiler (grc65).
+  Describes the GEOS resource compiler.
 
   <tag><htmlurl url="ld65.html" name="ld65.html"></tag>
   Describes the ld65 linker.
index 5aafc4bb8f4b9a44b5d65c531f116bda15679e09..f10c189b3da94203d294eb9090e253f6c74ae29d 100644 (file)
@@ -2,16 +2,17 @@ ifneq ($(shell echo),)
   CMD_EXE = 1
 endif
 
-PROGS = ar65  \
-        ca65  \
-        cc65  \
-        cl65  \
-        co65  \
-        da65  \
-        grc65 \
-        ld65  \
-        od65  \
-        sim65 \
+PROGS = ar65     \
+        ca65     \
+        cc65     \
+        chrcvt65 \
+        cl65     \
+        co65     \
+        da65     \
+        grc65    \
+        ld65     \
+        od65     \
+        sim65    \
         sp65
 
 .PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS)
diff --git a/src/chrcvt/error.c b/src/chrcvt/error.c
deleted file mode 100644 (file)
index 424080d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                                 error.c                                   */
-/*                                                                           */
-/*            Error handling for the chrcvt vector font converter            */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 1998-2009, Ullrich von Bassewitz                                      */
-/*                Roemerstrasse 52                                           */
-/*                D-70794 Filderstadt                                        */
-/* EMail:         uz@cc65.org                                                */
-/*                                                                           */
-/*                                                                           */
-/* This software is provided 'as-is', without any expressed or implied       */
-/* warranty.  In no event will the authors be held liable for any damages    */
-/* arising from the use of this software.                                    */
-/*                                                                           */
-/* Permission is granted to anyone to use this software for any purpose,     */
-/* including commercial applications, and to alter it and redistribute it    */
-/* freely, subject to the following restrictions:                            */
-/*                                                                           */
-/* 1. The origin of this software must not be misrepresented; you must not   */
-/*    claim that you wrote the original software. If you use this software   */
-/*    in a product, an acknowledgment in the product documentation would be  */
-/*    appreciated but is not required.                                       */
-/* 2. Altered source versions must be plainly marked as such, and must not   */
-/*    be misrepresented as being the original software.                      */
-/* 3. This notice may not be removed or altered from any source              */
-/*    distribution.                                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "error.h"
-
-
-
-/*****************************************************************************/
-/*                                   Code                                    */
-/*****************************************************************************/
-
-
-
-void Warning (const char* Format, ...)
-/* Print a warning message */
-{
-    va_list ap;
-    va_start (ap, Format);
-    fprintf (stderr, "Warning: ");
-    vfprintf (stderr, Format, ap);
-    putc ('\n', stderr);
-    va_end (ap);
-}
-
-
-
-void Error (const char* Format, ...)
-/* Print an error message and die */
-{
-    va_list ap;
-    va_start (ap, Format);
-    fprintf (stderr, "Error: ");
-    vfprintf (stderr, Format, ap);
-    putc ('\n', stderr);
-    va_end (ap);
-    exit (EXIT_FAILURE);
-}
-
-
-
-void Internal (const char* Format, ...)
-/* Print an internal error message and die */
-{
-    va_list ap;
-    va_start (ap, Format);
-    fprintf (stderr, "Internal error: ");
-    vfprintf (stderr, Format, ap);
-    putc ('\n', stderr);
-    va_end (ap);
-    exit (EXIT_FAILURE);
-}
-
-
-
diff --git a/src/chrcvt/error.h b/src/chrcvt/error.h
deleted file mode 100644 (file)
index 93f59cc..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                                 error.h                                   */
-/*                                                                           */
-/*            Error handling for the chrcvt vector font converter            */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 1998-2009, Ullrich von Bassewitz                                      */
-/*                Roemerstrasse 52                                           */
-/*                D-70794 Filderstadt                                        */
-/* EMail:         uz@cc65.org                                                */
-/*                                                                           */
-/*                                                                           */
-/* This software is provided 'as-is', without any expressed or implied       */
-/* warranty.  In no event will the authors be held liable for any damages    */
-/* arising from the use of this software.                                    */
-/*                                                                           */
-/* Permission is granted to anyone to use this software for any purpose,     */
-/* including commercial applications, and to alter it and redistribute it    */
-/* freely, subject to the following restrictions:                            */
-/*                                                                           */
-/* 1. The origin of this software must not be misrepresented; you must not   */
-/*    claim that you wrote the original software. If you use this software   */
-/*    in a product, an acknowledgment in the product documentation would be  */
-/*    appreciated but is not required.                                       */
-/* 2. Altered source versions must be plainly marked as such, and must not   */
-/*    be misrepresented as being the original software.                      */
-/* 3. This notice may not be removed or altered from any source              */
-/*    distribution.                                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-
-
-#ifndef ERROR_H
-#define ERROR_H
-
-
-
-/* common */
-#include "attrib.h"
-
-
-
-/*****************************************************************************/
-/*                                   Code                                    */
-/*****************************************************************************/
-
-
-
-void Warning (const char* Format, ...) attribute((format(printf,1,2)));
-/* Print a warning message */
-
-void Error (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
-/* Print an error message and die */
-
-void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
-/* Print an internal error message and die */
-
-
-
-/* End of error.h */
-
-#endif
-
-
-
diff --git a/src/chrcvt/main.c b/src/chrcvt/main.c
deleted file mode 100644 (file)
index 7b1c321..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                                  main.c                                   */
-/*                                                                           */
-/*             Main program of the chrcvt vector font converter              */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 2000-2011, Ullrich von Bassewitz                                      */
-/*                Roemerstrasse 52                                           */
-/*                D-70794 Filderstadt                                        */
-/* EMail:         uz@cc65.org                                                */
-/*                                                                           */
-/*                                                                           */
-/* This software is provided 'as-is', without any expressed or implied       */
-/* warranty.  In no event will the authors be held liable for any damages    */
-/* arising from the use of this software.                                    */
-/*                                                                           */
-/* Permission is granted to anyone to use this software for any purpose,     */
-/* including commercial applications, and to alter it and redistribute it    */
-/* freely, subject to the following restrictions:                            */
-/*                                                                           */
-/* 1. The origin of this software must not be misrepresented; you must not   */
-/*    claim that you wrote the original software. If you use this software   */
-/*    in a product, an acknowledgment in the product documentation would be  */
-/*    appreciated but is not required.                                       */
-/* 2. Altered source versions must be plainly marked as such, and must not   */
-/*    be misrepresented as being the original software.                      */
-/* 3. This notice may not be removed or altered from any source              */
-/*    distribution.                                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-/* common */
-#include "cmdline.h"
-#include "fname.h"
-#include "print.h"
-#include "strbuf.h"
-#include "xmalloc.h"
-#include "version.h"
-
-/* chrcvt */
-#include "error.h"
-
-
-
-/*
-** The following is a corrected doc from the BGI font editor toolkit:
-**
-**                      BGI Stroke File Format
-**
-** The structure of Borland .CHR (stroke) files is as follows:
-**
-** ;  offset 0h is a Borland header:
-** ;
-**         HeaderSize      equ     080h
-**         DataSize        equ     (size of font file)
-**         descr           equ     "Triplex font"
-**         fname           equ     "TRIP"
-**         MajorVersion    equ     1
-**         MinorVersion    equ     0
-**
-**         db      'PK',8,8
-**         db      'BGI ',descr,'  V'
-**         db      MajorVersion+'0'
-**         db      (MinorVersion / 10)+'0',(MinorVersion mod 10)+'0'
-**         db      ' - 19 October 1987',0DH,0AH
-**         db      'Copyright (c) 1987 Borland International', 0dh,0ah
-**         db      0,1ah                           ; null & ctrl-Z = end
-**
-**         dw      HeaderSize                      ; size of header
-**         db      fname                           ; font name
-**         dw      DataSize                        ; font file size
-**         db      MajorVersion,MinorVersion       ; version #'s
-**         db      1,0                             ; minimal version #'s
-**
-**         db      (HeaderSize - $) DUP (0)        ; pad out to header size
-**
-** At offset 80h starts data for the file:
-**
-** ;               80h     '+'  flags stroke file type
-** ;               81h-82h  number chars in font file (n)
-** ;               83h      undefined
-** ;               84h      ASCII value of first char in file
-** ;               85h-86h  offset to stroke definitions (8+3n)
-** ;               87h      scan flag (normally 0)
-** ;               88h      distance from origin to top of capital
-** ;               89h      distance from origin to baseline
-** ;               8Ah      distance from origin to bottom descender
-** ;               8Bh-8Fh  undefined
-** ;               90h      offsets to individual character definitions
-** ;               90h+2n   width table (one word per character)
-** ;               90h+3n   start of character definitions
-** ;
-** The individual character definitions consist of a variable number of words
-** describing the operations required to render a character. Each word
-** consists of an (x,y) coordinate pair and a two-bit opcode, encoded as shown
-** here:
-**
-** Byte 1          7   6   5   4   3   2   1   0     bit #
-**                op1  <seven bit signed X coord>
-**
-** Byte 2          7   6   5   4   3   2   1   0     bit #
-**                op2  <seven bit signed Y coord>
-**
-**
-**           Opcodes
-**
-**         op1=0  op2=0  End of character definition.
-**         op1=1  op2=0  Move the pointer to (x,y)
-**         op1=1  op2=1  Draw from current pointer to (x,y)
-*/
-
-
-
-/* The target file format is designed to be read by a cc65 compiled program
-** more easily. It should not be necessary to load the whole file into a
-** buffer to parse it, or seek within the file. Also using less memory if
-** possible would be fine. Therefore we use the following structure:
-**
-** Header portion:
-**      .byte   $54, $43, $48, $00              ; "TCH" version
-**      .word   <size of data portion>
-** Data portion:
-**      .byte   <top>                           ; Baseline to top
-**      .byte   <bottom>                        ; Baseline to bottom
-**      .byte   <height>                        ; Maximum char height
-**      .byte   <width>, ...                    ; $5F width bytes
-**      .word   <char definition offset>, ...   ; $5F char def offsets
-** Character definitions:
-**      .word   <converted opcode>, ...
-**      .byte   $80
-**
-** The baseline of the character is assume to be at position zero. top and
-** bottom are both positive values. The former extends in positive, the other
-** in negative direction of the baseline. height contains the sum of top and
-** bottom and is stored here just for easier handling.
-**
-** The opcodes get converted for easier handling: END is marked by bit 7
-** set in the first byte. The second byte of this opcode is not needed.
-** Bit 7 of the second byte marks a MOVE (bit 7 = 0) or DRAW (bit 7 = 1).
-**
-** The number of characters is fixed to $20..$7E (space to tilde), so character
-** widths and offsets can be stored in fixed size preallocated tables. The
-** space for the character definitions is allocated on the heap, it's size
-** is stored in the header.
-**
-** Above structure allows a program to read the header portion of the file,
-** validate it, then read the remainder of the file into memory in one chunk.
-** The character definition offsets will then be converted into pointers by
-** adding the character definition base pointer to each.
-*/
-
-
-
-/*****************************************************************************/
-/*                                   Data                                    */
-/*****************************************************************************/
-
-
-
-static unsigned FilesProcessed = 0;
-
-
-
-/*****************************************************************************/
-/*                                   Code                                    */
-/*****************************************************************************/
-
-
-
-static void Usage (void)
-/* Print usage information and exit */
-{
-    fprintf (stderr,
-             "Usage: %s [options] file [options] [file]\n"
-             "Short options:\n"
-             "  -h\t\t\tHelp (this text)\n"
-             "  -v\t\t\tBe more verbose\n"
-             "  -V\t\t\tPrint the version number and exit\n"
-             "\n"
-             "Long options:\n"
-             "  --help\t\tHelp (this text)\n"
-             "  --verbose\t\tBe more verbose\n"
-             "  --version\t\tPrint the version number and exit\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 OptVerbose (const char* Opt attribute ((unused)),
-                        const char* Arg attribute ((unused)))
-/* Increase verbosity */
-{
-    ++Verbosity;
-}
-
-
-
-static void OptVersion (const char* Opt attribute ((unused)),
-                        const char* Arg attribute ((unused)))
-/* Print the assembler version */
-{
-    fprintf (stderr,
-             "%s V%s - (C) Copyright 2009, Ullrich von Bassewitz\n",
-             ProgName, GetVersionAsString ());
-}
-
-
-
-static void ConvertChar (StrBuf* Data, const unsigned char* Buf, int Remaining)
-/* Convert data for one character. Original data is in Buf, converted data
-** will be placed in Data.
-*/
-{
-    /* Convert all drawing vectors for this character */
-    while (1) {
-
-        unsigned Op;
-
-        /* Check if we have enough data left */
-        if (Remaining < 2) {
-            Error ("End of file while parsing character definitions");
-        }
-
-        /* Get the next op word */
-        Op = (Buf[0] + (Buf[1] << 8)) & 0x8080;
-
-        /* Check the opcode */
-        switch (Op) {
-
-            case 0x0000:
-                /* End */
-                if (SB_IsEmpty (Data)) {
-                    /* No ops. We need to add an empty one */
-                    SB_AppendChar (Data, 0x00);
-                    SB_AppendChar (Data, 0x00);
-                }
-                /* Add an end marker to the last op in the buffer */
-                SB_GetBuf (Data)[SB_GetLen (Data) - 2] |= 0x80;
-                return;
-
-            case 0x0080:
-                /* Move */
-                SB_AppendChar (Data, Buf[0] & 0x7F);
-                SB_AppendChar (Data, Buf[1] & 0x7F);
-                break;
-
-            case 0x8000:
-                /* Invalid opcode */
-                Error ("Input file contains invalid opcode 0x8000");
-                break;
-
-            case 0x8080:
-                /* Draw */
-                SB_AppendChar (Data, Buf[0] & 0x7F);
-                SB_AppendChar (Data, Buf[1] | 0x80);
-                break;
-        }
-
-        /* Next Op */
-        Buf += 2;
-        Remaining -= 2;
-    }
-}
-
-
-
-static void ConvertFile (const char* Input, const char* Output)
-/* Convert one vector font file */
-{
-    /* The header of a BGI vector font file */
-    static const unsigned char ChrHeader[] = {
-        /* According to the Borland docs, the following should work, but it
-        ** doesn't. Seems like there are fonts that work, but don't have the
-        ** "BGI" string in the header. So we use just the PK\b\b mark as
-        ** a header.
-        **
-        ** 0x50, 0x4B, 0x08, 0x08, 0x42, 0x47, 0x49, 0x20
-        */
-        0x50, 0x4B, 0x08, 0x08
-    };
-
-    /* The header of a TGI vector font file */
-    unsigned char TchHeader[] = {
-        0x54, 0x43, 0x48, 0x00,         /* "TCH" version */
-        0x00, 0x00,                     /* size of char definitions */
-        0x00,                           /* Top */
-        0x00,                           /* Baseline */
-        0x00,                           /* Bottom */
-    };
-
-    long           Size;
-    unsigned char* Buf;
-    unsigned char* MsgEnd;
-    unsigned       FirstChar;
-    unsigned       CharCount;
-    unsigned       LastChar;
-    unsigned       Char;
-    unsigned       Offs;
-    const unsigned char* OffsetBuf;
-    const unsigned char* WidthBuf;
-    const unsigned char* VectorBuf;
-    StrBuf         Offsets  = AUTO_STRBUF_INITIALIZER;
-    StrBuf         VectorData = AUTO_STRBUF_INITIALIZER;
-
-
-    /* Try to open the file for reading */
-    FILE* F = fopen (Input, "rb");
-    if (F == 0) {
-        Error ("Cannot open input file `%s': %s", Input, strerror (errno));
-    }
-
-    /* Seek to the end and determine the size */
-    fseek (F, 0, SEEK_END);
-    Size = ftell (F);
-
-    /* Seek back to the start of the file */
-    fseek (F, 0, SEEK_SET);
-
-    /* Check if the size is reasonable */
-    if (Size > 32*1024) {
-        Error ("Input file `%s' is too large (max = 32k)", Input);
-    } else if (Size < 0x100) {
-        Error ("Input file `%s' is too small to be a vector font file", Input);
-    }
-
-    /* Allocate memory for the file */
-    Buf = xmalloc ((size_t) Size);
-
-    /* Read the file contents into the buffer */
-    if (fread (Buf, 1, (size_t) Size, F) != (size_t) Size) {
-        Error ("Error reading from input file `%s'", Input);
-    }
-
-    /* Close the file */
-    (void) fclose (F);
-
-    /* Verify the header */
-    if (memcmp (Buf, ChrHeader, sizeof (ChrHeader)) != 0) {
-        Error ("Invalid format for `%s': invalid header", Input);
-    }
-    MsgEnd = memchr (Buf + sizeof (ChrHeader), 0x1A, 0x80);
-    if (MsgEnd == 0) {
-        Error ("Invalid format for `%s': description not found", Input);
-    }
-    if (MsgEnd[1] != 0x80 || MsgEnd[2] != 0x00) {
-        Error ("Invalid format for `%s': wrong header size", Input);
-    }
-
-    /* We expect the file to hold chars from 0x20 (space) to 0x7E (tilde) */
-    FirstChar = Buf[0x84];
-    CharCount = Buf[0x81] + (Buf[0x82] << 8);
-    LastChar  = FirstChar + CharCount - 1;
-    if (FirstChar > 0x20 || LastChar < 0x7E) {
-        Print (stderr, 1, "FirstChar = $%04X, CharCount = %u\n",
-               FirstChar, CharCount);
-        Error ("File `%s' doesn't contain the chars we need", Input);
-    } else if (LastChar >= 0x100) {
-        Error ("File `%s' contains too many character definitions", Input);
-    }
-
-    /* Print the copyright from the header */
-    Print (stderr, 1, "%.*s\n", (int) (MsgEnd - Buf - 4), Buf+4);
-
-    /* Get pointers to the width table, the offset table and the vector data
-    ** table. The first two corrected for 0x20 as first entry.
-    */
-    OffsetBuf = Buf + 0x90 + ((0x20 - FirstChar) * 2);
-    WidthBuf  = Buf + 0x90 + (CharCount * 2) + (0x20 - FirstChar);
-    VectorBuf = Buf + 0x90 + (CharCount * 3);
-
-    /* Convert the characters */
-    for (Char = 0x20; Char <= 0x7E; ++Char, OffsetBuf += 2) {
-
-        int Remaining;
-
-        /* Add the offset to the offset table */
-        Offs = SB_GetLen (&VectorData);
-        SB_AppendChar (&Offsets, Offs & 0xFF);
-        SB_AppendChar (&Offsets, (Offs >> 8) & 0xFF);
-
-        /* Get the offset of the vector data in the BGI data buffer */
-        Offs = OffsetBuf[0] + (OffsetBuf[1] << 8);
-
-        /* Calculate the remaining data in the buffer for this character */
-        Remaining = Size - (Offs + (VectorBuf - Buf));
-
-        /* Check if the offset is valid */
-        if (Remaining <= 0) {
-            Error ("Invalid data offset in input file `%s'", Input);
-        }
-
-        /* Convert the vector data and place it into the buffer */
-        ConvertChar (&VectorData, VectorBuf + Offs, Remaining);
-    }
-
-    /* Complete the TCH header */
-    Offs = 3 + 0x5F + 2*0x5F + SB_GetLen (&VectorData);
-    TchHeader[4] = Offs & 0xFF;
-    TchHeader[5] = (Offs >> 8) & 0xFF;
-    TchHeader[6] = Buf[0x88];
-    TchHeader[7] = (unsigned char) -(signed char)(Buf[0x8A]);
-    TchHeader[8] = TchHeader[6] + TchHeader[7];
-
-    /* The baseline must be zero, otherwise we cannot convert */
-    if (Buf[0x89] != 0) {
-        Error ("Baseline of font in `%s' is not zero", Input);
-    }
-
-    /* If the output file is NULL, use the name of the input file with ".tch"
-    ** appended.
-    */
-    if (Output == 0) {
-        Output = MakeFilename (Input, ".tch");
-    }
-
-    /* Open the output file */
-    F = fopen (Output, "wb");
-    if (F == 0) {
-        Error ("Cannot open output file `%s': %s", Output, strerror (errno));
-    }
-
-    /* Write the header to the output file */
-    if (fwrite (TchHeader, 1, sizeof (TchHeader), F) != sizeof (TchHeader)) {
-        Error ("Error writing to `%s' (disk full?)", Output);
-    }
-
-    /* Write the width table to the output file */
-    if (fwrite (WidthBuf, 1, 0x5F, F) != 0x5F) {
-        Error ("Error writing to `%s' (disk full?)", Output);
-    }
-
-    /* Write the offsets to the output file */
-    if (fwrite (SB_GetConstBuf (&Offsets), 1, 0x5F * 2, F) != 0x5F * 2) {
-        Error ("Error writing to `%s' (disk full?)", Output);
-    }
-
-    /* Write the data to the output file */
-    Offs = SB_GetLen (&VectorData);
-    if (fwrite (SB_GetConstBuf (&VectorData), 1, Offs, F) != Offs) {
-        Error ("Error writing to `%s' (disk full?)", Output);
-    }
-
-    /* Close the output file */
-    if (fclose (F) != 0) {
-        Error ("Error closing to `%s': %s", Output, strerror (errno));
-    }
-
-    /* Done */
-}
-
-
-
-int main (int argc, char* argv [])
-/* Assembler main program */
-{
-    /* Program long options */
-    static const LongOpt OptTab[] = {
-        { "--help",             0,      OptHelp                 },
-        { "--verbose",          0,      OptVerbose              },
-        { "--version",          0,      OptVersion              },
-    };
-
-    unsigned I;
-
-    /* Initialize the cmdline module */
-    InitCmdLine (&argc, &argv, "chrcvt");
-
-    /* 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 'h':
-                    OptHelp (Arg, 0);
-                    break;
-
-                case 'v':
-                    OptVerbose (Arg, 0);
-                    break;
-
-                case 'V':
-                    OptVersion (Arg, 0);
-                    break;
-
-                default:
-                    UnknownOption (Arg);
-                    break;
-
-            }
-        } else {
-            /* Filename. Dump it. */
-            ConvertFile (Arg, 0);
-            ++FilesProcessed;
-        }
-
-        /* Next argument */
-        ++I;
-    }
-
-    /* Print a message if we did not process any files */
-    if (FilesProcessed == 0) {
-        fprintf (stderr, "%s: No input files\n", ProgName);
-    }
-
-    /* Success */
-    return EXIT_SUCCESS;
-}
-
-
-
diff --git a/src/chrcvt65/error.c b/src/chrcvt65/error.c
new file mode 100644 (file)
index 0000000..d6bc57f
--- /dev/null
@@ -0,0 +1,90 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 error.c                                   */
+/*                                                                           */
+/*           Error handling for the chrcvt65 vector font converter           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "error.h"
+
+
+
+/*****************************************************************************/
+/*                                   Code                                    */
+/*****************************************************************************/
+
+
+
+void Warning (const char* Format, ...)
+/* Print a warning message */
+{
+    va_list ap;
+    va_start (ap, Format);
+    fprintf (stderr, "Warning: ");
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+}
+
+
+
+void Error (const char* Format, ...)
+/* Print an error message and die */
+{
+    va_list ap;
+    va_start (ap, Format);
+    fprintf (stderr, "Error: ");
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+    exit (EXIT_FAILURE);
+}
+
+
+
+void Internal (const char* Format, ...)
+/* Print an internal error message and die */
+{
+    va_list ap;
+    va_start (ap, Format);
+    fprintf (stderr, "Internal error: ");
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+    exit (EXIT_FAILURE);
+}
+
+
+
diff --git a/src/chrcvt65/error.h b/src/chrcvt65/error.h
new file mode 100644 (file)
index 0000000..c5d1474
--- /dev/null
@@ -0,0 +1,68 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 error.h                                   */
+/*                                                                           */
+/*           Error handling for the chrcvt65 vector font converter           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef ERROR_H
+#define ERROR_H
+
+
+
+/* common */
+#include "attrib.h"
+
+
+
+/*****************************************************************************/
+/*                                   Code                                    */
+/*****************************************************************************/
+
+
+
+void Warning (const char* Format, ...) attribute((format(printf,1,2)));
+/* Print a warning message */
+
+void Error (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
+/* Print an error message and die */
+
+void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
+/* Print an internal error message and die */
+
+
+
+/* End of error.h */
+
+#endif
+
+
+
diff --git a/src/chrcvt65/main.c b/src/chrcvt65/main.c
new file mode 100644 (file)
index 0000000..8685e06
--- /dev/null
@@ -0,0 +1,538 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  main.c                                   */
+/*                                                                           */
+/*            Main program of the chrcvt65 vector font converter             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* common */
+#include "cmdline.h"
+#include "fname.h"
+#include "print.h"
+#include "strbuf.h"
+#include "xmalloc.h"
+#include "version.h"
+
+/* chrcvt65 */
+#include "error.h"
+
+
+
+/*
+** The following is a corrected doc from the BGI font editor toolkit:
+**
+**                      BGI Stroke File Format
+**
+** The structure of Borland .CHR (stroke) files is as follows:
+**
+** ;  offset 0h is a Borland header:
+** ;
+**         HeaderSize      equ     080h
+**         DataSize        equ     (size of font file)
+**         descr           equ     "Triplex font"
+**         fname           equ     "TRIP"
+**         MajorVersion    equ     1
+**         MinorVersion    equ     0
+**
+**         db      'PK',8,8
+**         db      'BGI ',descr,'  V'
+**         db      MajorVersion+'0'
+**         db      (MinorVersion / 10)+'0',(MinorVersion mod 10)+'0'
+**         db      ' - 19 October 1987',0DH,0AH
+**         db      'Copyright (c) 1987 Borland International', 0dh,0ah
+**         db      0,1ah                           ; null & ctrl-Z = end
+**
+**         dw      HeaderSize                      ; size of header
+**         db      fname                           ; font name
+**         dw      DataSize                        ; font file size
+**         db      MajorVersion,MinorVersion       ; version #'s
+**         db      1,0                             ; minimal version #'s
+**
+**         db      (HeaderSize - $) DUP (0)        ; pad out to header size
+**
+** At offset 80h starts data for the file:
+**
+** ;               80h     '+'  flags stroke file type
+** ;               81h-82h  number chars in font file (n)
+** ;               83h      undefined
+** ;               84h      ASCII value of first char in file
+** ;               85h-86h  offset to stroke definitions (8+3n)
+** ;               87h      scan flag (normally 0)
+** ;               88h      distance from origin to top of capital
+** ;               89h      distance from origin to baseline
+** ;               8Ah      distance from origin to bottom descender
+** ;               8Bh-8Fh  undefined
+** ;               90h      offsets to individual character definitions
+** ;               90h+2n   width table (one word per character)
+** ;               90h+3n   start of character definitions
+** ;
+** The individual character definitions consist of a variable number of words
+** describing the operations required to render a character. Each word
+** consists of an (x,y) coordinate pair and a two-bit opcode, encoded as shown
+** here:
+**
+** Byte 1          7   6   5   4   3   2   1   0     bit #
+**                op1  <seven bit signed X coord>
+**
+** Byte 2          7   6   5   4   3   2   1   0     bit #
+**                op2  <seven bit signed Y coord>
+**
+**
+**           Opcodes
+**
+**         op1=0  op2=0  End of character definition.
+**         op1=1  op2=0  Move the pointer to (x,y)
+**         op1=1  op2=1  Draw from current pointer to (x,y)
+*/
+
+
+
+/* The target file format is designed to be read by a cc65 compiled program
+** more easily. It should not be necessary to load the whole file into a
+** buffer to parse it, or seek within the file. Also using less memory if
+** possible would be fine. Therefore we use the following structure:
+**
+** Header portion:
+**      .byte   $54, $43, $48, $00              ; "TCH" version
+**      .word   <size of data portion>
+** Data portion:
+**      .byte   <top>                           ; Baseline to top
+**      .byte   <bottom>                        ; Baseline to bottom
+**      .byte   <height>                        ; Maximum char height
+**      .byte   <width>, ...                    ; $5F width bytes
+**      .word   <char definition offset>, ...   ; $5F char def offsets
+** Character definitions:
+**      .word   <converted opcode>, ...
+**      .byte   $80
+**
+** The baseline of the character is assume to be at position zero. top and
+** bottom are both positive values. The former extends in positive, the other
+** in negative direction of the baseline. height contains the sum of top and
+** bottom and is stored here just for easier handling.
+**
+** The opcodes get converted for easier handling: END is marked by bit 7
+** set in the first byte. The second byte of this opcode is not needed.
+** Bit 7 of the second byte marks a MOVE (bit 7 = 0) or DRAW (bit 7 = 1).
+**
+** The number of characters is fixed to $20..$7E (space to tilde), so character
+** widths and offsets can be stored in fixed size preallocated tables. The
+** space for the character definitions is allocated on the heap, it's size
+** is stored in the header.
+**
+** Above structure allows a program to read the header portion of the file,
+** validate it, then read the remainder of the file into memory in one chunk.
+** The character definition offsets will then be converted into pointers by
+** adding the character definition base pointer to each.
+*/
+
+
+
+/*****************************************************************************/
+/*                                   Data                                    */
+/*****************************************************************************/
+
+
+
+static unsigned FilesProcessed = 0;
+
+
+
+/*****************************************************************************/
+/*                                   Code                                    */
+/*****************************************************************************/
+
+
+
+static void Usage (void)
+/* Print usage information and exit */
+{
+    fprintf (stderr,
+             "Usage: %s [options] file [options] [file]\n"
+             "Short options:\n"
+             "  -h\t\t\tHelp (this text)\n"
+             "  -v\t\t\tBe more verbose\n"
+             "  -V\t\t\tPrint the version number and exit\n"
+             "\n"
+             "Long options:\n"
+             "  --help\t\tHelp (this text)\n"
+             "  --verbose\t\tBe more verbose\n"
+             "  --version\t\tPrint the version number and exit\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 OptVerbose (const char* Opt attribute ((unused)),
+                        const char* Arg attribute ((unused)))
+/* Increase verbosity */
+{
+    ++Verbosity;
+}
+
+
+
+static void OptVersion (const char* Opt attribute ((unused)),
+                        const char* Arg attribute ((unused)))
+/* Print the assembler version */
+{
+    fprintf (stderr,
+             "%s V%s\n", ProgName, GetVersionAsString ());
+}
+
+
+
+static void ConvertChar (StrBuf* Data, const unsigned char* Buf, int Remaining)
+/* Convert data for one character. Original data is in Buf, converted data
+** will be placed in Data.
+*/
+{
+    /* Convert all drawing vectors for this character */
+    while (1) {
+
+        unsigned Op;
+
+        /* Check if we have enough data left */
+        if (Remaining < 2) {
+            Error ("End of file while parsing character definitions");
+        }
+
+        /* Get the next op word */
+        Op = (Buf[0] + (Buf[1] << 8)) & 0x8080;
+
+        /* Check the opcode */
+        switch (Op) {
+
+            case 0x0000:
+                /* End */
+                if (SB_IsEmpty (Data)) {
+                    /* No ops. We need to add an empty one */
+                    SB_AppendChar (Data, 0x00);
+                    SB_AppendChar (Data, 0x00);
+                }
+                /* Add an end marker to the last op in the buffer */
+                SB_GetBuf (Data)[SB_GetLen (Data) - 2] |= 0x80;
+                return;
+
+            case 0x0080:
+                /* Move */
+                SB_AppendChar (Data, Buf[0] & 0x7F);
+                SB_AppendChar (Data, Buf[1] & 0x7F);
+                break;
+
+            case 0x8000:
+                /* Invalid opcode */
+                Error ("Input file contains invalid opcode 0x8000");
+                break;
+
+            case 0x8080:
+                /* Draw */
+                SB_AppendChar (Data, Buf[0] & 0x7F);
+                SB_AppendChar (Data, Buf[1] | 0x80);
+                break;
+        }
+
+        /* Next Op */
+        Buf += 2;
+        Remaining -= 2;
+    }
+}
+
+
+
+static void ConvertFile (const char* Input, const char* Output)
+/* Convert one vector font file */
+{
+    /* The header of a BGI vector font file */
+    static const unsigned char ChrHeader[] = {
+        /* According to the Borland docs, the following should work, but it
+        ** doesn't. Seems like there are fonts that work, but don't have the
+        ** "BGI" string in the header. So we use just the PK\b\b mark as
+        ** a header.
+        **
+        ** 0x50, 0x4B, 0x08, 0x08, 0x42, 0x47, 0x49, 0x20
+        */
+        0x50, 0x4B, 0x08, 0x08
+    };
+
+    /* The header of a TGI vector font file */
+    unsigned char TchHeader[] = {
+        0x54, 0x43, 0x48, 0x00,         /* "TCH" version */
+        0x00, 0x00,                     /* size of char definitions */
+        0x00,                           /* Top */
+        0x00,                           /* Baseline */
+        0x00,                           /* Bottom */
+    };
+
+    long           Size;
+    unsigned char* Buf;
+    unsigned char* MsgEnd;
+    unsigned       FirstChar;
+    unsigned       CharCount;
+    unsigned       LastChar;
+    unsigned       Char;
+    unsigned       Offs;
+    const unsigned char* OffsetBuf;
+    const unsigned char* WidthBuf;
+    const unsigned char* VectorBuf;
+    StrBuf         Offsets  = AUTO_STRBUF_INITIALIZER;
+    StrBuf         VectorData = AUTO_STRBUF_INITIALIZER;
+
+
+    /* Try to open the file for reading */
+    FILE* F = fopen (Input, "rb");
+    if (F == 0) {
+        Error ("Cannot open input file `%s': %s", Input, strerror (errno));
+    }
+
+    /* Seek to the end and determine the size */
+    fseek (F, 0, SEEK_END);
+    Size = ftell (F);
+
+    /* Seek back to the start of the file */
+    fseek (F, 0, SEEK_SET);
+
+    /* Check if the size is reasonable */
+    if (Size > 32*1024) {
+        Error ("Input file `%s' is too large (max = 32k)", Input);
+    } else if (Size < 0x100) {
+        Error ("Input file `%s' is too small to be a vector font file", Input);
+    }
+
+    /* Allocate memory for the file */
+    Buf = xmalloc ((size_t) Size);
+
+    /* Read the file contents into the buffer */
+    if (fread (Buf, 1, (size_t) Size, F) != (size_t) Size) {
+        Error ("Error reading from input file `%s'", Input);
+    }
+
+    /* Close the file */
+    (void) fclose (F);
+
+    /* Verify the header */
+    if (memcmp (Buf, ChrHeader, sizeof (ChrHeader)) != 0) {
+        Error ("Invalid format for `%s': invalid header", Input);
+    }
+    MsgEnd = memchr (Buf + sizeof (ChrHeader), 0x1A, 0x80);
+    if (MsgEnd == 0) {
+        Error ("Invalid format for `%s': description not found", Input);
+    }
+    if (MsgEnd[1] != 0x80 || MsgEnd[2] != 0x00) {
+        Error ("Invalid format for `%s': wrong header size", Input);
+    }
+
+    /* We expect the file to hold chars from 0x20 (space) to 0x7E (tilde) */
+    FirstChar = Buf[0x84];
+    CharCount = Buf[0x81] + (Buf[0x82] << 8);
+    LastChar  = FirstChar + CharCount - 1;
+    if (FirstChar > 0x20 || LastChar < 0x7E) {
+        Print (stderr, 1, "FirstChar = $%04X, CharCount = %u\n",
+               FirstChar, CharCount);
+        Error ("File `%s' doesn't contain the chars we need", Input);
+    } else if (LastChar >= 0x100) {
+        Error ("File `%s' contains too many character definitions", Input);
+    }
+
+    /* Print the copyright from the header */
+    Print (stderr, 1, "%.*s\n", (int) (MsgEnd - Buf - 4), Buf+4);
+
+    /* Get pointers to the width table, the offset table and the vector data
+    ** table. The first two corrected for 0x20 as first entry.
+    */
+    OffsetBuf = Buf + 0x90 + ((0x20 - FirstChar) * 2);
+    WidthBuf  = Buf + 0x90 + (CharCount * 2) + (0x20 - FirstChar);
+    VectorBuf = Buf + 0x90 + (CharCount * 3);
+
+    /* Convert the characters */
+    for (Char = 0x20; Char <= 0x7E; ++Char, OffsetBuf += 2) {
+
+        int Remaining;
+
+        /* Add the offset to the offset table */
+        Offs = SB_GetLen (&VectorData);
+        SB_AppendChar (&Offsets, Offs & 0xFF);
+        SB_AppendChar (&Offsets, (Offs >> 8) & 0xFF);
+
+        /* Get the offset of the vector data in the BGI data buffer */
+        Offs = OffsetBuf[0] + (OffsetBuf[1] << 8);
+
+        /* Calculate the remaining data in the buffer for this character */
+        Remaining = Size - (Offs + (VectorBuf - Buf));
+
+        /* Check if the offset is valid */
+        if (Remaining <= 0) {
+            Error ("Invalid data offset in input file `%s'", Input);
+        }
+
+        /* Convert the vector data and place it into the buffer */
+        ConvertChar (&VectorData, VectorBuf + Offs, Remaining);
+    }
+
+    /* Complete the TCH header */
+    Offs = 3 + 0x5F + 2*0x5F + SB_GetLen (&VectorData);
+    TchHeader[4] = Offs & 0xFF;
+    TchHeader[5] = (Offs >> 8) & 0xFF;
+    TchHeader[6] = Buf[0x88];
+    TchHeader[7] = (unsigned char) -(signed char)(Buf[0x8A]);
+    TchHeader[8] = TchHeader[6] + TchHeader[7];
+
+    /* The baseline must be zero, otherwise we cannot convert */
+    if (Buf[0x89] != 0) {
+        Error ("Baseline of font in `%s' is not zero", Input);
+    }
+
+    /* If the output file is NULL, use the name of the input file with ".tch"
+    ** appended.
+    */
+    if (Output == 0) {
+        Output = MakeFilename (Input, ".tch");
+    }
+
+    /* Open the output file */
+    F = fopen (Output, "wb");
+    if (F == 0) {
+        Error ("Cannot open output file `%s': %s", Output, strerror (errno));
+    }
+
+    /* Write the header to the output file */
+    if (fwrite (TchHeader, 1, sizeof (TchHeader), F) != sizeof (TchHeader)) {
+        Error ("Error writing to `%s' (disk full?)", Output);
+    }
+
+    /* Write the width table to the output file */
+    if (fwrite (WidthBuf, 1, 0x5F, F) != 0x5F) {
+        Error ("Error writing to `%s' (disk full?)", Output);
+    }
+
+    /* Write the offsets to the output file */
+    if (fwrite (SB_GetConstBuf (&Offsets), 1, 0x5F * 2, F) != 0x5F * 2) {
+        Error ("Error writing to `%s' (disk full?)", Output);
+    }
+
+    /* Write the data to the output file */
+    Offs = SB_GetLen (&VectorData);
+    if (fwrite (SB_GetConstBuf (&VectorData), 1, Offs, F) != Offs) {
+        Error ("Error writing to `%s' (disk full?)", Output);
+    }
+
+    /* Close the output file */
+    if (fclose (F) != 0) {
+        Error ("Error closing to `%s': %s", Output, strerror (errno));
+    }
+
+    /* Done */
+}
+
+
+
+int main (int argc, char* argv [])
+/* Assembler main program */
+{
+    /* Program long options */
+    static const LongOpt OptTab[] = {
+        { "--help",             0,      OptHelp                 },
+        { "--verbose",          0,      OptVerbose              },
+        { "--version",          0,      OptVersion              },
+    };
+
+    unsigned I;
+
+    /* Initialize the cmdline module */
+    InitCmdLine (&argc, &argv, "chrcvt65");
+
+    /* 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 'h':
+                    OptHelp (Arg, 0);
+                    break;
+
+                case 'v':
+                    OptVerbose (Arg, 0);
+                    break;
+
+                case 'V':
+                    OptVersion (Arg, 0);
+                    break;
+
+                default:
+                    UnknownOption (Arg);
+                    break;
+
+            }
+        } else {
+            /* Filename. Dump it. */
+            ConvertFile (Arg, 0);
+            ++FilesProcessed;
+        }
+
+        /* Next argument */
+        ++I;
+    }
+
+    /* Print a message if we did not process any files */
+    if (FilesProcessed == 0) {
+        fprintf (stderr, "%s: No input files\n", ProgName);
+    }
+
+    /* Success */
+    return EXIT_SUCCESS;
+}
+
+
+