//
-// RMAC - Reboot's Macro Assembler for all Atari computers
+// RMAC - Renamed Macro Assembler for all Atari computers
// RMAC.C - Main Application Code
-// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
int list_pag = 1; // Enable listing pagination by default
int verb_flag; // Be verbose about what's going on
int m6502; // 1, assembling 6502 code
-int as68_flag; // as68 kludge mode
int glob_flag; // Assume undefined symbols are global
int lsym_flag; // Include local symbols in object file
int optim_warn_flag; // Warn about possible short branches
char * objfname; // Object filename pointer
char * firstfname; // First source filename
char * cmdlnexec; // Executable name, pointer to ARGV[0]
+char searchpatha[512] = { 0 }; // Buffer to hold searchpath when specified
char * searchpath = NULL; // Search path for include files
char defname[] = "noname.o"; // Default output filename
-int optim_flags[OPT_COUNT]; // Specific optimisations on/off matrix
+int optim_flags[OPT_COUNT_ALL] = { 0 }; // Specific optimisations on/off matrix
int activecpu = CPU_68000; // Active 68k CPU (68000 by default)
int activefpu = FPU_NONE; // Active FPU (none by default)
int org68k_active = 0; // .org switch for 68k (only with RAW output format)
*s++ &= 0xDF;
}
-
//
// Manipulate file extension.
//
return name;
}
+static int is_sep(char c)
+{
+ const char *seps = PATH_SEPS;
+
+ for (seps = PATH_SEPS; *seps; seps++) {
+ if (*seps == c)
+ return 1;
+ }
+
+ return 0;
+}
//
// Return 'item'nth element of semicolon-seperated pathnames specified in the
return 0;
while (itemno--)
- while (*s != EOS && *s++ != ';')
+ while (*s != EOS && !is_sep(*s++))
;
if (*s == EOS)
return 0;
- while (*s != EOS && *s != ';')
+ while (*s != EOS && !is_sep(*s))
*buf++ = *s++;
*buf++ = EOS;
return 1;
}
-
//
// Display command line help
//
" -n Don't do things behind your back in RISC assembler\n"
" -o file Output file name\n"
" +o[value] Turn a specific optimisation on\n"
- " Available optimisation values and default settings:\n"
- " o0: Absolute long addresses to word (on)\n"
- " o1: move.l #x,dn/an to moveq (on)\n"
- " o2: Word branches to short (on)\n"
- " o3: Outer displacement 0(an) to (an) (off)\n"
- " o4: lea size(An),An to addq #size,An (off)\n"
- " o5: 68020+ Absolute long base/outer displacement to word (off)\n"
- " o6: Null branches to NOP (off)\n"
- " o7: clr.l Dx to moveq #0,Dx (off)\n"
- " o8: adda.w/l #x,Dy to addq.w/l #x,Dy (off)\n"
- " o9: adda.w/l #x,Dy to lea x(Dy),Dy (off)\n"
- " op: Enforce PC relative (off)\n"
+ " Available optimisation switches:\n"
+ " o0: Absolute long addresses to word\n"
+ " o1: move.l #x,dn/an to moveq\n"
+ " o2: Word branches to short\n"
+ " o3: Outer displacement 0(an) to (an)\n"
+ " o4: lea size(An),An to addq #size,An\n"
+ " o5: 68020+ Absolute long base/outer disp. to word\n"
+ " o6: Null branches to NOP\n"
+ " o7: clr.l Dx to moveq #0,Dx\n"
+ " o8: adda.w/l #x,Dy to addq.w/l #x,Dy\n"
+ " o9: adda.w/l #x,Ay to lea x(Dy),Ay\n"
+ " o10: 56001 Use short format for immediate values if possible\n"
+ " o11: 56001 Auto convert short addressing mode to long (default: on)\n"
+ " o30: Enforce PC relative (alternative name: op)\n"
" ~o[value] Turn a specific optimisation off\n"
" +oall Turn all optimisations on\n"
" ~oall Turn all optimisations off\n"
"| '__| '_ ` _ \\ / _` |/ __|\n"
"| | | | | | | | (_| | (__ \n"
"|_| |_| |_| |_|\\__,_|\\___|\n"
- "\nReboot's Macro Assembler\n"
- "Copyright (C) 199x Landon Dyer, 2011-2020 Reboot\n"
+ "\nRenamed Macro Assembler\n"
+ "Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends\n"
"V%01i.%01i.%01i %s (%s)\n\n", MAJOR, MINOR, PATCH, __DATE__, PLATFORM);
}
-
//
// Parse optimisation options
//
else if (*optstring != '~')
return ERROR;
+ if (optstring[2] == 0)
+ return error(".opt called with zero arguments");
+
if ((optstring[2] == 'a' || optstring[2] == 'A')
&& (optstring[3] == 'l' || optstring[3] == 'L')
&& (optstring[4] == 'l' || optstring[4] == 'L'))
else
{
int opt_no = atoi(&optstring[2]);
+
if ((opt_no >= 0) && (opt_no < OPT_COUNT))
{
optim_flags[opt_no] = onoff;
optstring += 3;
+
// If opt_no is 2 digits then consume an extra character.
// Sounds a bit sleazy but we know we're not going to hit
- // more than 100 optimisation switches so this should be fine.
- // If we do hit that number then it'll probably be time to burn
- // the whole codebase and start from scratch.
+ // more than 100 optimisation switches so this should be
+ // fine. If we do hit that number then it'll probably be
+ // time to burn the whole codebase and start from scratch.
if (opt_no > 9)
optstring++;
}
{
return ERROR;
}
+
if (*optstring == ',')
optstring++;
}
return OK;
}
-
//
// Process command line arguments and do an assembly
//
int fd; // File descriptor
char fnbuf[FNSIZ]; // Filename buffer
int i; // Iterator
+ int current_path_index = 0; // Iterator for search paths
errcnt = 0; // Initialize error count
listing = 0; // Initialize listing level
list_flag = 0; // Initialize listing flag
verb_flag = perm_verb_flag; // Initialize verbose flag
- as68_flag = 0; // Initialize as68 kludge mode
glob_flag = 0; // Initialize .globl flag
optim_warn_flag = 0; // Initialize short branch flag
debug = 0; // Initialize debug flag
- searchpath = NULL; // Initialize search path
objfname = NULL; // Initialize object filename
list_fname = NULL; // Initialize listing filename
err_fname = NULL; // Initialize error filename
case 'i': // Set directory search path
case 'I':
{
- searchpath = argv[argno] + 2;
+ strcat(searchpatha, argv[argno] + 2);
+ strcat(searchpatha, ";");
+ searchpath = searchpatha;
// Check to see if include paths actually exist
- if (strlen(searchpath) > 0)
- {
- DIR * test = opendir(searchpath);
+ char current_path[256];
- if (test == NULL)
+ for(i=current_path_index; nthpath("RMACPATH", i, current_path)!=0; i++)
+ {
+ if (strlen(current_path) > 0)
{
- printf("Invalid include path: %s\n", searchpath);
- errcnt++;
- return errcnt;
- }
+ DIR * test = opendir(current_path);
+
+ if (test == NULL)
+ {
+ printf("Invalid include path: %s\n", current_path);
+ errcnt++;
+ return errcnt;
+ }
- closedir(test);
+ closedir(test);
+ }
}
+ current_path_index = i - 1;
break;
}
case 'l': // Produce listing file
return errcnt;
}
-
//
// Determine processor endianess
//
return 1;
}
-
//
// Application entry point
//
{
perm_verb_flag = 0; // Clobber "permanent" verbose flag
legacy_flag = 1; // Default is legacy mode on (:-P)
-
- // Set legacy optimisation flags to on and everything else to off
- memset(optim_flags, 0, OPT_COUNT * sizeof(int));
- optim_flags[OPT_ABS_SHORT] =
- optim_flags[OPT_MOVEL_MOVEQ] =
- optim_flags[OPT_BSR_BCC_S] = 1;
+ optim_flags[OPT_56K_SHORT] = 1; // This ensures compatibilty with Motorola's 56k assembler
cmdlnexec = argv[0]; // Obtain executable name
endian = GetEndianess(); // Get processor endianess
return 0;
}
-