/* */
/* */
/* */
-/* (C) 1998 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2008, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "check.h"
+#include "strbuf.h"
+#include "strutil.h"
/* ca65 */
#include "error.h"
-/* Predefined packages */
-
-/* Generic macros */
-static char MacGeneric[] =
- ".macro add Arg1, Arg2\n"
- " clc\n"
- " .if .paramcount = 2\n"
- " adc Arg1, Arg2\n"
- " .else\n"
- " adc Arg1\n"
- " .endif\n"
- ".endmacro\n"
- ".macro sub Arg1, Arg2\n"
- " sec\n"
- " .if .paramcount = 2\n"
- " sbc Arg1, Arg2\n"
- " .else\n"
- " sbc Arg1\n"
- " .endif\n"
- ".endmacro\n";
-
-/* Long branch macros */
-static char MacLongBranch[] =
- ".macro jeq Target\n"
- " .if .match(Target, 0)\n"
- " bne *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " beq Target\n"
- " .else\n"
- " bne *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jne Target\n"
- " .if .match(Target, 0)\n"
- " beq *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bne Target\n"
- " .else\n"
- " beq *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jmi Target\n"
- " .if .match(Target, 0)\n"
- " bpl *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bmi Target\n"
- " .else\n"
- " bpl *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jpl Target\n"
- " .if .match(Target, 0)\n"
- " bmi *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bpl Target\n"
- " .else\n"
- " bmi *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jcs Target\n"
- " .if .match(Target, 0)\n"
- " bcc *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bcs Target\n"
- " .else\n"
- " bcc *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jcc Target\n"
- " .if .match(Target, 0)\n"
- " bcs *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bcc Target\n"
- " .else\n"
- " bcs *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jvs Target\n"
- " .if .match(Target, 0)\n"
- " bvc *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bvs Target\n"
- " .else\n"
- " bvc *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n"
- ".macro jvc Target\n"
- " .if .match(Target, 0)\n"
- " bvs *+5\n"
- " jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
- " bvc Target\n"
- " .else\n"
- " bvs *+5\n"
- " jmp Target\n"
- " .endif\n"
- ".endmacro\n";
-
-/* Commodore specific macros */
-static char MacCBM[] =
- ".macro scrcode str\n"
- " .repeat .strlen(str), i\n"
- " .if (.strat(str, i) >= '@' .and .strat(str, i) <= 'z')\n"
- " .byte .strat(str, i) - '@'\n"
- " .elseif (.strat(str, i) >= 'A' .and .strat(str, i) <= 'Z')\n"
- " .byte .strat(str, i) - 'A' + 65\n"
- " .elseif (.strat(str, i) = '[')\n"
- " .byte 27\n"
- " .elseif (.strat(str, i) = ']')\n"
- " .byte 29\n"
- " .elseif (.strat(str, i) = '^')\n"
- " .byte 30\n"
- " .elseif (.strat(str, i) = '_')\n"
- " .byte 31\n"
- " .else\n"
- " .byte .strat(str, i)\n"
- " .endif\n"
- " .endrepeat\n"
- ".endmacro\n";
-
-
-
+/* Predefined macro packages converted into C strings by a perl script */
+#include "atari.inc"
+#include "cbm.inc"
+#include "cpu.inc"
+#include "generic.inc"
+#include "longbranch.inc"
/* Table with pointers to the different packages */
-static char* MacPackages [] = {
- MacGeneric,
- MacLongBranch,
- MacCBM
+static struct {
+ const char* Name;
+ char* Package;
+} MacPackages[MAC_COUNT] = {
+ /* Packages sorted by id */
+ { "atari", MacAtari },
+ { "cbm", MacCBM },
+ { "cpu", MacCPU },
+ { "generic", MacGeneric },
+ { "longbranch", MacLongBranch },
};
+/* Directory that contains standard macro package files */
+static StrBuf MacPackDir = STATIC_STRBUF_INITIALIZER;
+
/*****************************************************************************/
-void InsertMacPack (unsigned Id)
+int MacPackFind (const StrBuf* Name)
+/* Find a macro package by name. The function will either return the id or
+ * -1 if the package name was not found.
+ */
+{
+ int I;
+
+ for (I = 0; I < MAC_COUNT; ++I) {
+ if (SB_CompareStr (Name, MacPackages[I].Name) == 0) {
+ /* Found */
+ return I;
+ }
+ }
+
+ /* Not found */
+ return -1;
+}
+
+
+
+void MacPackInsert (int Id)
/* Insert the macro package with the given id in the input stream */
{
/* Check the parameter */
- CHECK (Id < sizeof (MacPackages) / sizeof (MacPackages [0]));
+ CHECK (Id >= 0 && Id < MAC_COUNT);
+
+ /* If we have a macro package directory given, load a file from the
+ * directory, otherwise use the builtin stuff.
+ */
+ if (SB_IsEmpty (&MacPackDir)) {
- /* Insert the package */
- NewInputData (MacPackages [Id], 0);
+ /* Insert the builtin package */
+ NewInputData (MacPackages[Id].Package, 0);
+
+ } else {
+
+ StrBuf Filename = AUTO_STRBUF_INITIALIZER;
+
+ /* Build the complete file name */
+ SB_Copy (&Filename, &MacPackDir);
+ SB_AppendStr (&Filename, MacPackages[Id].Name);
+ SB_AppendStr (&Filename, ".mac");
+ SB_Terminate (&Filename);
+
+ /* Open the macro package as include file */
+ NewInputFile (SB_GetConstBuf (&Filename));
+
+ /* Destroy the contents of Filename */
+ SB_Done (&Filename);
+
+ }
+}
+
+
+
+void MacPackSetDir (const StrBuf* Dir)
+/* Set a directory where files for macro packages can be found. Standard is
+ * to use the builtin packages. For debugging macro packages, external files
+ * can be used.
+ */
+{
+ /* Copy the directory name to the buffer */
+ SB_Copy (&MacPackDir, Dir);
+
+ /* Make sure that the last character is a path delimiter */
+ if (SB_NotEmpty (&MacPackDir)) {
+ char C = SB_LookAtLast (&MacPackDir);
+ if (C != '\\' && C != '/') {
+ SB_AppendChar (&MacPackDir, '/');
+ }
+ }
+
+ /* Terminate the buffer so it's usable as a C string */
+ SB_Terminate (&MacPackDir);
}