2011-12-27 00:50:27 +02:00
//
2021-03-08 00:43:25 +02:00
// RMAC - Renamed Macro Assembler for all Atari computers
2011-12-27 00:50:27 +02:00
// RMAC.H - Main Application Code
2022-05-31 01:40:19 +03:00
// Copyright (C) 199x Landon Dyer, 2011-2022 Reboot and Friends
2011-12-27 00:50:27 +02:00
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
2015-02-19 16:56:14 +02:00
// Source utilised with the kind permission of Landon Dyer
2011-12-27 00:50:27 +02:00
//
# ifndef __RMAC_H__
# define __RMAC_H__
2016-09-13 03:16:03 +03:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <sys/types.h>
# include <sys/stat.h>
2011-12-27 00:50:27 +02:00
//
// TARGET SPECIFIC BUILD SETTINGS
//
2018-01-21 16:25:06 +02:00
# if defined(WIN32) || defined(WIN64)
2016-09-13 03:16:03 +03:00
# include <io.h>
# include <fcntl.h>
2023-03-20 21:57:12 +02:00
# include "dirent_lose.h"
2015-01-16 19:16:33 +02:00
// Release platform - windows
# define PLATFORM "Win32"
2012-11-23 18:39:09 +02:00
# define _OPEN_FLAGS _O_TRUNC|_O_CREAT|_O_BINARY|_O_RDWR
# define _OPEN_INC _O_RDONLY|_O_BINARY
2017-04-14 23:52:31 +03:00
# define _PERM_MODE _S_IREAD|_S_IWRITE
2020-08-27 08:46:16 +03:00
# define PATH_SEPS ";"
2022-07-18 10:35:28 +03:00
# define realpath(_fn, _abs) _fullpath((_abs), (_fn), _MAX_PATH)
2018-01-21 16:25:06 +02:00
2012-11-23 18:39:09 +02:00
# ifdef _MSC_VER
# if _MSC_VER > 1000
# pragma warning(disable:4996)
# endif
2015-08-30 21:12:34 +03:00
2015-10-07 06:23:59 +03:00
// Makes warnings double clickable on visual studio (ggn)
2015-08-30 21:12:34 +03:00
# define STRINGIZE_HELPER(x) #x
# define STRINGIZE(x) STRINGIZE_HELPER(x)
2015-10-07 06:23:59 +03:00
# define WARNING(desc) __pragma(message(__FILE__ "(" STRINGIZE(__LINE__) ") : Warning: " #desc))
2017-04-14 23:52:31 +03:00
# define inline __inline
2015-08-30 21:12:34 +03:00
// usage:
2015-10-07 06:23:59 +03:00
// WARNING(FIXME: Code removed because...)
2015-08-30 21:12:34 +03:00
2015-10-22 19:41:58 +03:00
# else
2016-09-13 06:27:30 +03:00
// If we're not compiling for Visual Studio let's assume that we're using
// some flavour of gcc instead. So let's use the gcc compliant macro
// instead. If some weirdo uses something else (I dunno, Intel compiler or
// something?) this is probably going to explode spectacularly. Let's wait
// for the fireworks!
2015-10-22 19:41:58 +03:00
# define DO_PRAGMA(x) _Pragma (#x)
# define WARNING(desc) DO_PRAGMA(message (#desc))
2012-11-23 18:39:09 +02:00
# endif
2015-08-30 21:12:34 +03:00
2023-03-20 21:57:12 +02:00
// Ever since Visual Studio... 2017? 2019? the following constants come
// defined in the platform SDK, which leads to endless warnings from the
// compiler. So let's just put the pacifier on and undef them, sheesh! (No,
// we won't rename the defines, we've been here since 1986, Visual Studio
// wasn't even a glimpse in the milkman's eyes, if you catch my drift)
# undef CONST
# undef ERROR
# undef TEXT
2017-04-14 23:52:31 +03:00
# else
2023-03-20 21:57:12 +02:00
# include <dirent.h>
2012-11-23 18:39:09 +02:00
# ifdef __GCCUNIX__
2017-04-14 23:52:31 +03:00
2016-09-13 03:16:03 +03:00
# include <sys/fcntl.h>
# include <unistd.h>
2018-01-21 16:25:06 +02:00
// Release platform - Linux or mac OS-X
# define PLATFORM "Linux / OSX"
2012-11-23 18:39:09 +02:00
# define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR
# define _OPEN_INC O_RDONLY
2016-09-13 03:16:03 +03:00
# define _PERM_MODE S_IRUSR|S_IWUSR
2020-08-27 08:46:16 +03:00
# define PATH_SEPS ";:"
2017-04-15 00:47:23 +03:00
# ifdef __MINGW32__
# define off64_t long
# define off_t long
# undef _OPEN_FLAGS
# undef _OPEN_INC
# define _OPEN_FLAGS _O_TRUNC|_O_CREAT|_O_BINARY|_O_RDWR
# define _OPEN_INC O_RDONLY|_O_BINARY
# endif
2015-10-07 06:23:59 +03:00
// WARNING WARNING WARNING
# define DO_PRAGMA(x) _Pragma (#x)
# define WARNING(desc) DO_PRAGMA(message (#desc))
2018-01-21 16:25:06 +02:00
# else
2017-04-14 23:52:31 +03:00
// Release platform - not specified
2016-09-13 03:16:03 +03:00
# include <sys/fcntl.h>
2015-01-16 19:16:33 +02:00
# define PLATFORM "Unknown"
2012-11-23 18:39:09 +02:00
# define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR
# define _OPEN_INC O_RDONLY
2016-09-13 03:16:03 +03:00
# define _PERM_MODE S_IREAD|S_IWRITE
2020-08-27 08:46:16 +03:00
# define PATH_SEPS ":;"
2016-09-13 03:16:03 +03:00
// Defined here, even though the platform may not support it...
2015-10-07 06:23:59 +03:00
# define DO_PRAGMA(x) _Pragma (#x)
# define WARNING(desc) DO_PRAGMA(message (#desc))
2012-11-23 18:39:09 +02:00
# endif
2018-01-21 16:25:06 +02:00
2011-12-27 00:50:27 +02:00
# endif
2018-01-21 16:25:06 +02:00
2017-04-14 23:52:31 +03:00
//
// Endian related, for safe handling of endian-sensitive data
// USAGE: GETBExx() is *always* an rvalue, a = pointer to a uint8_t,
// r = offset from 0. SETBExx(), v = value to write into 'a'
//
# define GETBE16(a, r) \
( ( ( uint16_t ) ( a ) [ ( r + 0 ) ] < < 8 ) | ( ( uint16_t ) ( a ) [ ( r + 1 ) ] ) )
# define GETBE32(a, r) \
( ( ( uint32_t ) ( a ) [ ( r + 0 ) ] < < 24 ) | ( ( uint32_t ) ( a ) [ ( r + 1 ) ] < < 16 ) \
| ( ( uint32_t ) ( a ) [ ( r + 2 ) ] < < 8 ) | ( ( uint32_t ) ( a ) [ ( r + 3 ) ] ) )
# define GETBE64(a, r) \
( ( ( uint64_t ) ( a ) [ ( r + 0 ) ] < < 56 ) | ( ( uint64_t ) ( a ) [ ( r + 1 ) ] < < 48 ) \
| ( ( uint64_t ) ( a ) [ ( r + 2 ) ] < < 40 ) | ( ( uint64_t ) ( a ) [ ( r + 3 ) ] < < 32 ) \
| ( ( uint64_t ) ( a ) [ ( r + 4 ) ] < < 24 ) | ( ( uint64_t ) ( a ) [ ( r + 5 ) ] < < 16 ) \
| ( ( uint64_t ) ( a ) [ ( r + 6 ) ] < < 8 ) | ( ( uint64_t ) ( a ) [ ( r + 7 ) ] ) )
# define SETBE16(a, r, v) \
{ ( a ) [ ( r + 0 ) ] = ( uint8_t ) ( ( v ) > > 8 ) ; \
( a ) [ ( r + 1 ) ] = ( uint8_t ) ( ( v ) & 0xFF ) ; }
# define SETBE32(a, r, v) \
{ ( a ) [ ( r + 0 ) ] = ( uint8_t ) ( ( v ) > > 24 ) ; \
( a ) [ ( r + 1 ) ] = ( uint8_t ) ( ( ( v ) > > 16 ) & 0xFF ) ; \
( a ) [ ( r + 2 ) ] = ( uint8_t ) ( ( ( v ) > > 8 ) & 0xFF ) ; \
( a ) [ ( r + 3 ) ] = ( uint8_t ) ( ( v ) & 0xFF ) ; }
# define SETBE64(a, r, v) \
{ ( a ) [ ( r + 0 ) ] = ( uint8_t ) ( ( v ) > > 56 ) ; \
( a ) [ ( r + 1 ) ] = ( uint8_t ) ( ( ( v ) > > 48 ) & 0xFF ) ; \
( a ) [ ( r + 2 ) ] = ( uint8_t ) ( ( ( v ) > > 40 ) & 0xFF ) ; \
( a ) [ ( r + 3 ) ] = ( uint8_t ) ( ( ( v ) > > 32 ) & 0xFF ) ; \
( a ) [ ( r + 4 ) ] = ( uint8_t ) ( ( ( v ) > > 24 ) & 0xFF ) ; \
( a ) [ ( r + 5 ) ] = ( uint8_t ) ( ( ( v ) > > 16 ) & 0xFF ) ; \
( a ) [ ( r + 6 ) ] = ( uint8_t ) ( ( ( v ) > > 8 ) & 0xFF ) ; \
( a ) [ ( r + 7 ) ] = ( uint8_t ) ( ( v ) & 0xFF ) ; }
2017-04-20 22:29:31 +03:00
// In 6502 mode, turns out we need this:
# define SETLE16(a, r, v) \
{ ( a ) [ ( r + 0 ) ] = ( uint8_t ) ( ( v ) & 0xFF ) ; \
( a ) [ ( r + 1 ) ] = ( uint8_t ) ( ( v ) > > 8 ) ; }
2019-08-08 02:24:52 +03:00
// In DSP56001 mode, this is useful:
# define SETBE24(a, v) \
{ ( a ) [ 0 ] = ( uint8_t ) ( ( ( v ) > > 16 ) & 0xFF ) ; \
( a ) [ 1 ] = ( uint8_t ) ( ( ( v ) > > 8 ) & 0xFF ) ; \
( a ) [ 2 ] = ( uint8_t ) ( ( v ) & 0xFF ) ; }
2017-04-14 23:52:31 +03:00
// Byteswap crap
# define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
# define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
2017-11-30 02:52:47 +02:00
# define BYTESWAP64(x) (BYTESWAP32(x >> 32) | (BYTESWAP32(x & 0xFFFFFFFF) << 32))
2017-04-14 23:52:31 +03:00
# define WORDSWAP32(x) ((((x) & 0x0000FFFF) << 16) | (((x) & 0xFFFF0000) >> 16))
2012-11-24 21:48:52 +02:00
//
// Non-target specific stuff
//
2012-01-01 20:05:45 +02:00
# include <inttypes.h>
2012-11-24 21:48:52 +02:00
# include "symbol.h"
2011-12-27 00:50:27 +02:00
2012-01-01 20:05:45 +02:00
# define BYTE uint8_t
# define WORD uint16_t
# define LONG uint32_t
2011-12-27 00:50:27 +02:00
# define VOID void
2017-05-07 05:07:36 +03:00
# define ERROR (-1) // Generic error return
# define EOS '\0' // End of string
# define SPACE ' ' // ASCII space
2011-12-27 00:50:27 +02:00
# define SLASHCHAR ' / '
# define SLASHSTRING " / "
2017-05-07 05:07:36 +03:00
# define FNSIZ 128 // Maximum size of a filename
# define OK 0 // OK return
# define DEBUG if (debug) // Debug conditional
# define MAXARGV 100 // Maximum number of commandline args
# define STDOUT 1 // Standard output
# define ERROUT 2 // Error output
2011-12-27 00:50:27 +02:00
# define CREATMASK 0
// Object code formats
2017-10-26 15:24:25 +03:00
enum
{
2017-11-21 15:54:55 +02:00
ALCYON , // Alcyon/DRI C object format
2017-10-26 15:24:25 +03:00
BSD , // BSD object format
ELF , // ELF object format
LOD , // DSP 56001 object format
P56 , // DSP 56001 object format
XEX , // COM/EXE/XEX/whatever a8 object format
2020-01-09 11:40:02 +02:00
RAW , // Output at absolute address
2022-12-22 00:37:53 +02:00
C64PRG , // C64 .PRG format
2017-10-26 15:24:25 +03:00
} ;
2011-12-27 00:50:27 +02:00
2017-11-21 15:54:55 +02:00
// Assembler token
# define TOKEN uint32_t
2011-12-27 00:50:27 +02:00
// Pointer type that can point to (almost) anything
# define PTR union _ptr
PTR
{
2017-11-29 15:57:58 +02:00
uint8_t * cp ; // Char pointer
uint16_t * wp ; // WORD pointer
uint32_t * lp ; // LONG pointer
uint32_t * u32 ; // 32-bit pointer
uint64_t * u64 ; // 64-bit pointer
uint32_t lw ; // LONG (for some reason)
SYM * * sy ; // SYM pointer
TOKEN * tk ; // TOKEN pointer
2018-01-21 16:25:06 +02:00
double * dp ; // Double pointer
int64_t * i64 ; // 64-bit signed int pointer
2011-12-27 00:50:27 +02:00
} ;
// Symbol spaces
2017-05-07 05:07:36 +03:00
# define LABEL 0 // User-defined symbol
# define MACRO 1 // Macro definition
# define MACARG 2 // Macro argument
2022-07-18 09:20:21 +03:00
# define DBGSYM 3 // stabs debug symbol
2017-05-07 05:07:36 +03:00
# define SY_UNDEF -1 // Undefined (lookup never matches it)
2011-12-27 00:50:27 +02:00
// Symbol and expression attributes
2017-05-07 05:07:36 +03:00
# define DEFINED 0x8000 // Symbol has been defined
# define GLOBAL 0x4000 // Symbol has been .GLOBL'd
# define COMMON 0x2000 // Symbol has been .COMM'd
# define REFERENCED 0x1000 // Symbol has been referenced
# define EQUATED 0x0800 // Symbol was equated
# define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list
2017-10-26 15:24:25 +03:00
# define FLOAT 0x0200 // Symbol is a floating point value
2020-01-04 18:24:57 +02:00
# define RISCREG 0x0100 // Symbol is a RISC register
2011-12-27 00:50:27 +02:00
// Expression spaces, ORed with symbol and expression attributes above
2017-05-07 05:07:36 +03:00
# define ABS 0x0000 // In absolute space
# define TEXT 0x0001 // Relative to text
# define DATA 0x0002 // Relative to data
# define BSS 0x0004 // Relative to BSS
2019-08-08 02:24:52 +03:00
//OK, this is bad, mmkay? These are treated as indices into an array which means that this was never meant to be defined this way--at least if it was, it was a compromise that has come home to bite us all in the ass. !!! FIX !!!
2017-05-07 05:07:36 +03:00
# define M6502 0x0008 // 6502/microprocessor (absolute)
2018-06-23 19:57:21 +03:00
# define M56001P 0x0010 // DSP 56001 Program RAM
# define M56001X 0x0020 // DSP 56001 X RAM
# define M56001Y 0x0040 // DSP 56001 Y RAM
# define M56001L 0x0080 // DSP 56001 L RAM
2019-08-08 02:24:52 +03:00
# define TDB (TEXT|DATA|BSS) // Mask for TEXT+DATA+BSS
2018-06-23 19:57:21 +03:00
# define M56KPXYL (M56001P|M56001X|M56001Y|M56001L) // Mask for 56K stuff
2011-12-27 00:50:27 +02:00
2017-04-14 23:52:31 +03:00
// Sizes
2017-05-07 05:07:36 +03:00
# define SIZB 0x0001 // .b
# define SIZW 0x0002 // .w
# define SIZL 0x0004 // .l
# define SIZN 0x0008 // no .(size) specifier
2017-11-21 15:54:55 +02:00
# define SIZD 0x0010 // .d (FPU double precision real)
2017-05-07 05:07:36 +03:00
# define SIZS 0x0020 // .s (FPU single precision real)
# define SIZX 0x0040 // .x (FPU extended precision real)
# define SIZP 0x0080 // .p (FPU pakced decimal real)
2017-11-21 15:54:55 +02:00
# define SIZQ 0x0100 // .q (quad word)
2011-12-27 00:50:27 +02:00
2022-10-17 19:49:32 +03:00
// Extended attributes
2017-05-07 05:07:36 +03:00
# define EQUATEDREG 0x0008 // Equated register symbol
2011-12-27 00:50:27 +02:00
# define UNDEF_EQUR 0x0010
# define EQUATEDCC 0x0020
# define UNDEF_CC 0x0040
2016-09-07 13:00:55 +03:00
// Optimisation defines
enum
{
2020-11-08 16:27:45 +02:00
// These will be set to on/off when .opt "+Oall"/"~Oall" is called
2017-04-14 23:52:31 +03:00
OPT_ABS_SHORT = 0 ,
OPT_MOVEL_MOVEQ = 1 ,
OPT_BSR_BCC_S = 2 ,
2020-07-17 23:23:08 +03:00
OPT_OUTER_DISP = 3 ,
2017-05-07 05:07:36 +03:00
OPT_LEA_ADDQ = 4 ,
2020-07-17 23:23:08 +03:00
OPT_020_DISP = 5 , // 020+ base and outer displacements (bd, od) absolute long to short
2017-11-29 21:28:44 +02:00
OPT_NULL_BRA = 6 ,
OPT_CLR_DX = 7 ,
2018-01-23 10:57:01 +02:00
OPT_ADDA_ADDQ = 8 ,
OPT_ADDA_LEA = 9 ,
2021-07-16 15:04:22 +03:00
OPT_56K_SHORT = 10 ,
OPT_56K_AUTO_LONG = 11 ,
2020-11-08 16:27:45 +02:00
OPT_COUNT , // Dummy, used to count number of optimisation switches
// These will be unaffected by "Oall"
2021-07-16 15:04:22 +03:00
OPT_PC_RELATIVE = 30 , // Enforce PC relative
2020-11-08 16:27:45 +02:00
OPT_COUNT_ALL // Dummy, used to count all switches
2016-09-07 13:00:55 +03:00
} ;
2017-04-20 22:29:31 +03:00
// Exported variables
2011-12-27 00:50:27 +02:00
extern int verb_flag ;
extern int debug ;
extern int rgpu , rdsp ;
2018-02-26 05:39:59 +02:00
extern int robjproc ;
2017-05-05 17:51:11 +03:00
extern int dsp56001 ;
2011-12-27 00:50:27 +02:00
extern int err_flag ;
extern int err_fd ;
2011-12-27 01:54:45 +02:00
extern char * firstfname ;
2011-12-27 00:50:27 +02:00
extern int list_fd ;
2017-04-27 10:24:37 +03:00
extern int list_pag ;
2017-04-19 19:42:26 +03:00
extern int m6502 ;
2011-12-27 00:50:27 +02:00
extern int list_flag ;
extern int glob_flag ;
extern int lsym_flag ;
2022-07-18 10:35:28 +03:00
extern int dsym_flag ;
2020-07-17 23:23:08 +03:00
extern int optim_warn_flag ;
2011-12-27 00:50:27 +02:00
extern int obj_format ;
2014-01-13 05:44:04 +02:00
extern int legacy_flag ;
2017-04-14 23:52:31 +03:00
extern int prg_flag ; // 1 = write ".PRG" relocatable executable
2015-11-14 19:57:21 +02:00
extern LONG PRGFLAGS ;
2020-11-08 16:27:45 +02:00
extern int optim_flags [ OPT_COUNT_ALL ] ;
2017-05-07 05:07:36 +03:00
extern int activecpu ;
extern int activefpu ;
2020-01-09 11:40:02 +02:00
extern uint32_t org68k_address ;
extern int org68k_active ;
2022-03-24 13:28:09 +02:00
extern int * regbase ;
extern int * regtab ;
extern int * regcheck ;
extern int * regaccept ;
2022-10-26 21:30:21 +03:00
extern uint32_t used_architectures ;
2011-12-27 00:50:27 +02:00
2015-01-16 19:16:33 +02:00
// Exported functions
2018-02-26 05:39:59 +02:00
void strtoupper ( char * s ) ;
2011-12-27 01:54:45 +02:00
char * fext ( char * , char * , int ) ;
2011-12-27 00:50:27 +02:00
int nthpath ( char * , int , char * ) ;
2016-09-07 14:18:24 +03:00
int ParseOptimization ( char * optstring ) ;
2011-12-27 00:50:27 +02:00
# endif // __RMAC_H__
2015-01-16 19:16:33 +02:00