+#include "peeph.rul"
+#include "peeph-z80.rul"
+};
+
+static char _gbz80_defaultRules[] =
+{
+#include "peeph.rul"
+#include "peeph-gbz80.rul"
+};
+
+Z80_OPTS z80_opts;
+
+static OPTION _z80_options[] =
+ {
+ { 0, "--callee-saves-bc", &z80_opts.calleeSavesBC, "Force a called function to always save BC" },
+ { 0, "--portmode=", NULL, "Determine PORT I/O mode (z80/z180)" },
+ { 0, NULL }
+ };
+
+static OPTION _gbz80_options[] =
+ {
+ { 0, "--callee-saves-bc", &z80_opts.calleeSavesBC, "Force a called function to always save BC" },
+ { 0, NULL }
+ };
+
+typedef enum
+ {
+ /* Must be first */
+ ASM_TYPE_ASXXXX,
+ ASM_TYPE_RGBDS,
+ ASM_TYPE_ISAS,
+ ASM_TYPE_Z80ASM
+ }
+ASM_TYPE;
+
+static struct
+ {
+ ASM_TYPE asmType;
+ /* determine if we can register a parameter */
+ int regParams;
+ }
+_G;
+
+static char *_keywords[] =
+{
+ "sfr",
+ "nonbanked",
+ "banked",
+ "at", //.p.t.20030714 adding support for 'sfr at ADDR' construct
+ "_naked", //.p.t.20030714 adding support for '_naked' functions
+ "critical",
+ "interrupt",
+ NULL
+};
+
+extern PORT gbz80_port;
+extern PORT z80_port;
+
+#include "mappings.i"
+
+static builtins _z80_builtins[] = {
+ /* Disabled for now.
+ { "__builtin_strcpy", "v", 2, {"cg*", "cg*" } },
+ { "__builtin_memcpy", "cg*", 3, {"cg*", "cg*", "ui" } },
+ */
+ { NULL , NULL,0, {NULL}}
+};
+
+static void
+_z80_init (void)
+{
+ z80_opts.sub = SUB_Z80;
+ asm_addTree (&_asxxxx_z80);
+}
+
+static void
+_gbz80_init (void)
+{
+ z80_opts.sub = SUB_GBZ80;
+}
+
+static void
+_reset_regparm (void)
+{
+ _G.regParams = 0;
+}
+
+static int
+_reg_parm (sym_link * l, bool reentrant)
+{
+ if (options.noRegParams)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (_G.regParams == 2)
+ {
+ return FALSE;
+ }
+ else
+ {
+ _G.regParams++;
+ return TRUE;
+ }
+ }
+}
+static int
+_process_pragma (const char *sz)
+{
+ if( startsWith( sz, "bank=" ) || startsWith( sz, "bank " ))
+ {
+ char buffer[128];
+
+ if (sz[4]=='=')
+ werror(W_DEPRECATED_PRAGMA, "bank=");
+
+ strncpy (buffer, sz + 5, sizeof (buffer));
+ buffer[sizeof (buffer) - 1 ] = '\0';
+ chomp (buffer);
+ if (isdigit ((unsigned char)buffer[0]))
+ {
+
+ }
+ else if (!strcmp (buffer, "BASE"))
+ {
+ strcpy (buffer, "HOME");
+ }
+ if (isdigit ((unsigned char)buffer[0]))
+ {
+ /* Arg was a bank number. Handle in an ASM independent
+ way. */
+ char num[128];
+ strncpy (num, sz + 5, sizeof (num));
+ num[sizeof (num) -1] = '\0';
+ chomp (num);
+
+ switch (_G.asmType)
+ {
+ case ASM_TYPE_ASXXXX:
+ sprintf (buffer, "CODE_%s", num);
+ break;
+ case ASM_TYPE_RGBDS:
+ sprintf (buffer, "CODE,BANK[%s]", num);
+ break;
+ case ASM_TYPE_ISAS:
+ /* PENDING: what to use for ISAS? */
+ sprintf (buffer, "CODE,BANK(%s)", num);
+ break;
+ default:
+ wassert (0);
+ }
+ }
+ gbz80_port.mem.code_name = Safe_strdup (buffer);
+ code->sname = gbz80_port.mem.code_name;
+ return 0;
+ }
+ else if( startsWith( sz, "portmode=" ) || startsWith( sz, "portmode " ))
+ { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
+ char bfr[128];
+
+ if (sz[8]=='=')
+ werror(W_DEPRECATED_PRAGMA, "portmode=");
+
+ strncpy( bfr, sz + 9, sizeof (bfr));
+ bfr[sizeof (bfr) - 1] = '\0';
+ chomp( bfr );
+
+ if ( !strcmp( bfr, "z80" )){ z80_opts.port_mode = 80; }
+ else if( !strcmp( bfr, "z180" )){ z80_opts.port_mode = 180; }
+ else if( !strcmp( bfr, "save" )){ z80_opts.port_back = z80_opts.port_mode; }
+ else if( !strcmp( bfr, "restore" )){ z80_opts.port_mode = z80_opts.port_back; }
+ else return( 1 );
+
+ return( 0 );
+ }
+
+ return 1;
+}
+
+static const char *_gbz80_rgbasmCmd[] =
+{
+ "rgbasm", "-o\"$1.o\"", "\"$1.asm\"", NULL
+};
+
+static const char *_gbz80_rgblinkCmd[] =
+{
+ "xlink", "-tg", "-n\"$1.sym\"", "-m\"$1.map\"", "-zFF", "\"$1.lnk\"", NULL
+};
+
+static void
+_gbz80_rgblink (void)
+{
+ FILE *lnkfile;
+
+ /* first we need to create the <filename>.lnk file */
+ sprintf (scratchFileName, "%s.lnk", dstFileName);
+ if (!(lnkfile = fopen (scratchFileName, "w")))
+ {
+ werror (E_FILE_OPEN_ERR, scratchFileName);
+ exit (1);
+ }
+
+ fprintf (lnkfile, "[Objects]\n");
+
+ fprintf (lnkfile, "%s.o\n", dstFileName);
+
+ fputStrSet(lnkfile, relFilesSet);
+
+ fprintf (lnkfile, "\n[Libraries]\n");
+ /* additional libraries if any */
+ fputStrSet(lnkfile, libFilesSet);
+
+ fprintf (lnkfile, "\n[Output]\n" "%s.gb", dstFileName);
+
+ fclose (lnkfile);
+
+ buildCmdLine (buffer,port->linker.cmd, dstFileName, NULL, NULL, NULL);
+ /* call the linker */
+ if (my_system (buffer))
+ {
+ perror ("Cannot exec linker");
+ exit (1);
+ }