mirror of http://shamusworld.gotdns.org/git/rmac
446 lines
8.0 KiB
C
446 lines
8.0 KiB
C
//
|
|
// RMAC - Macro Assembler for all Atari computers
|
|
// DEBUG.C - Debugging Messages
|
|
// 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
|
|
//
|
|
|
|
#include "debug.h"
|
|
#include "6502.h"
|
|
#include "amode.h"
|
|
#include "direct.h"
|
|
#include "expr.h"
|
|
#include "mark.h"
|
|
#include "sect.h"
|
|
#include "token.h"
|
|
|
|
|
|
static int siztab[4] = { 3, 5, 9, 9 };
|
|
static PTR tp;
|
|
|
|
|
|
//
|
|
// Print 'c' visibly
|
|
//
|
|
int visprt(char c)
|
|
{
|
|
if (c < 0x20 || c >= 0x7F)
|
|
putchar('.');
|
|
else
|
|
putchar(c);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Print expression, return ptr to just past the ENDEXPR
|
|
//
|
|
TOKEN * printexpr(TOKEN * tokenptr)
|
|
{
|
|
if (tokenptr != NULL)
|
|
{
|
|
while (*tokenptr != ENDEXPR)
|
|
{
|
|
switch ((int)*tokenptr++)
|
|
{
|
|
case SYMBOL:
|
|
printf("'%s' ", symbolPtr[*tokenptr]->sname);
|
|
tokenptr++;
|
|
break;
|
|
case CONST:
|
|
tp.u32 = tokenptr;
|
|
printf("$%lX ", *tp.u64++);
|
|
tokenptr = tp.u32;
|
|
break;
|
|
case ACONST:
|
|
printf("ACONST=($%X,$%X) ", *tokenptr, tokenptr[1]);
|
|
tokenptr += 2;
|
|
break;
|
|
default:
|
|
printf("%c ", (char)tokenptr[-1]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tokenptr + 1;
|
|
}
|
|
|
|
|
|
//
|
|
// Dump data in a chunk (and maybe others) in the appropriate format
|
|
//
|
|
int chdump(CHUNK * ch, int format)
|
|
{
|
|
while (ch != NULL)
|
|
{
|
|
printf("chloc=$%08X, chsize=$%X\n", ch->chloc, ch->ch_size);
|
|
mdump(ch->chptr, ch->ch_size, format, ch->chloc);
|
|
ch = ch->chnext;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Dump fixup records in printable format
|
|
//
|
|
int fudump(FIXUP * fup)
|
|
{
|
|
for(; fup!=NULL;)
|
|
{
|
|
uint32_t attr = fup->attr;
|
|
uint32_t loc = fup->loc;
|
|
uint16_t file = fup->fileno;
|
|
uint16_t line = fup->lineno;
|
|
|
|
printf("$%08X $%08X %d.%d: ", attr, loc, (int)file, (int)line);
|
|
|
|
if (attr & FU_EXPR)
|
|
{
|
|
uint16_t esiz = ExpressionLength(fup->expr);
|
|
printf("(%d long) ", (int)esiz);
|
|
printexpr(fup->expr);
|
|
}
|
|
else
|
|
printf("`%s' ;", fup->symbol->sname);
|
|
|
|
if ((attr & FUMASKRISC) == FU_JR)
|
|
printf(" *=$%X", fup->orgaddr);
|
|
|
|
printf("\n");
|
|
|
|
fup = fup->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Dump marks
|
|
//
|
|
int mudump(void)
|
|
{
|
|
MCHUNK * mch;
|
|
PTR p;
|
|
WORD from;
|
|
WORD w;
|
|
LONG loc;
|
|
SYM * symbol;
|
|
|
|
from = 0;
|
|
|
|
for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
|
|
{
|
|
printf("mch=$%p mcptr=$%08X mcalloc=$%X mcused=$%X\n",
|
|
mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
|
|
|
|
p = mch->mcptr;
|
|
|
|
for(;;)
|
|
{
|
|
w = *p.wp++;
|
|
|
|
if (w & MCHEND)
|
|
break;
|
|
|
|
symbol = NULL;
|
|
loc = *p.lp++;
|
|
|
|
if (w & MCHFROM)
|
|
from = *p.wp++;
|
|
|
|
if (w & MSYMBOL)
|
|
symbol = *p.sy++;
|
|
|
|
printf("m=$%04X to=%d loc=$%X from=%d siz=%s",
|
|
w, w & 0x00FF, loc, from, (w & MLONG) ? "long" : "word");
|
|
|
|
if (symbol != NULL)
|
|
printf(" sym=`%s'", symbol->sname);
|
|
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Dump memory from 'start' for 'count' bytes; `flg' is the following ORed
|
|
// together:
|
|
// 0 - bytes
|
|
// 1 - words
|
|
// 2 - longwords
|
|
//
|
|
// if `base' is not -1, then print it at the start of each line, incremented
|
|
// accordingly.
|
|
//
|
|
int mdump(char * start, LONG count, int flg, LONG base)
|
|
{
|
|
int i, j, k;
|
|
j = 0;
|
|
|
|
for(i=0; i<(int)count;)
|
|
{
|
|
if ((i & 15) == 0)
|
|
{
|
|
if (j < i)
|
|
{
|
|
printf(" ");
|
|
|
|
while (j < i)
|
|
visprt(start[j++]);
|
|
|
|
putchar('\n');
|
|
}
|
|
|
|
j = i;
|
|
|
|
if (base != -1)
|
|
printf("%08X ", base);
|
|
}
|
|
|
|
switch (flg & 3)
|
|
{
|
|
case 0:
|
|
printf("%02X ", start[i] & 0xFF);
|
|
i++;
|
|
break;
|
|
case 1:
|
|
printf("%02X%02X ", start[i] & 0xFF, start[i+1] & 0xFF);
|
|
i += 2;
|
|
break;
|
|
case 2:
|
|
printf("%02X%02X%02X%02X ", start[i] & 0xFF, start[i+1] & 0xFF,
|
|
start[i+2] & 0xFF, start[i+3] & 0xFF);
|
|
i += 4;
|
|
break;
|
|
}
|
|
|
|
if (base != -1)
|
|
base += 1 << (flg & 3);
|
|
}
|
|
|
|
// Print remaining bit of ASCII; the hairy expression computes the number
|
|
// of spaces to print to make the ASCII line up nicely.
|
|
if (j != i)
|
|
{
|
|
k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
|
|
|
|
while (k--)
|
|
putchar(' ');
|
|
|
|
printf(" ");
|
|
|
|
while (j < i)
|
|
visprt(start[j++]);
|
|
|
|
putchar('\n');
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Dump list of tokens on stdout in printable form
|
|
//
|
|
int dumptok(TOKEN * tk)
|
|
{
|
|
int flg = 0;
|
|
|
|
while (*tk != EOL)
|
|
{
|
|
if (flg++)
|
|
printf(" ");
|
|
|
|
if (*tk >= 128)
|
|
{
|
|
printf("REG=%u", *tk++ - 128);
|
|
continue;
|
|
}
|
|
|
|
switch ((int)*tk++)
|
|
{
|
|
case CONST: // CONST <value>
|
|
tp.u32 = tk;
|
|
printf("CONST=%lu", *tp.u64++);
|
|
tk = tp.u32;
|
|
break;
|
|
case STRING: // STRING <address>
|
|
printf("STRING='%s'", string[*tk++]);
|
|
break;
|
|
case SYMBOL: // SYMBOL <address>
|
|
printf("SYMBOL='%s'", string[*tk++]);
|
|
break;
|
|
case EOL: // End of line
|
|
printf("EOL");
|
|
break;
|
|
case TKEOF: // End of file (or macro)
|
|
printf("TKEOF");
|
|
break;
|
|
case DEQUALS: // ==
|
|
printf("DEQUALS");
|
|
break;
|
|
case DCOLON: // ::
|
|
printf("DCOLON");
|
|
break;
|
|
case GE: // >=
|
|
printf("GE");
|
|
break;
|
|
case LE: // <=
|
|
printf("LE");
|
|
break;
|
|
case NE: // <> or !=
|
|
printf("NE");
|
|
break;
|
|
case SHR: // >>
|
|
printf("SHR");
|
|
break;
|
|
case SHL: // <<
|
|
printf("SHL");
|
|
break;
|
|
default:
|
|
printf("%c", (int)tk[-1]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void DumpTokens(TOKEN * tokenBuffer)
|
|
{
|
|
// printf("Tokens [%X]: ", sloc);
|
|
|
|
for(TOKEN * t=tokenBuffer; *t!=EOL; t++)
|
|
{
|
|
if (*t == COLON)
|
|
printf("[COLON]");
|
|
else if (*t == CONST)
|
|
{
|
|
tp.u32 = t + 1;
|
|
printf("[CONST: $%lX]", *tp.u64);
|
|
t += 2;
|
|
}
|
|
else if (*t == ACONST)
|
|
{
|
|
printf("[ACONST: $%X, $%X]", (uint32_t)t[1], (uint32_t)t[2]);
|
|
t += 2;
|
|
}
|
|
else if (*t == STRING)
|
|
{
|
|
t++;
|
|
printf("[STRING:\"%s\"]", string[*t]);
|
|
}
|
|
else if (*t == SYMBOL)
|
|
{
|
|
t++;
|
|
printf("[SYMBOL:\"%s\"]", string[*t]);
|
|
}
|
|
else if (*t == EOS)
|
|
printf("[EOS]");
|
|
else if (*t == TKEOF)
|
|
printf("[TKEOF]");
|
|
else if (*t == DEQUALS)
|
|
printf("[DEQUALS]");
|
|
else if (*t == SET)
|
|
printf("[SET]");
|
|
else if (*t == REG)
|
|
printf("[REG]");
|
|
else if (*t == DCOLON)
|
|
printf("[DCOLON]");
|
|
else if (*t == GE)
|
|
printf("[GE]");
|
|
else if (*t == LE)
|
|
printf("[LE]");
|
|
else if (*t == NE)
|
|
printf("[NE]");
|
|
else if (*t == SHR)
|
|
printf("[SHR]");
|
|
else if (*t == SHL)
|
|
printf("[SHL]");
|
|
else if (*t == UNMINUS)
|
|
printf("[UNMINUS]");
|
|
else if (*t == DOTB)
|
|
printf("[DOTB]");
|
|
else if (*t == DOTW)
|
|
printf("[DOTW]");
|
|
else if (*t == DOTL)
|
|
printf("[DOTL]");
|
|
else if (*t == DOTI)
|
|
printf("[DOTI]");
|
|
else if (*t == ENDEXPR)
|
|
printf("[ENDEXPR]");
|
|
else if (*t == CR_ABSCOUNT)
|
|
printf("[CR_ABSCOUNT]");
|
|
else if (*t == CR_FILESIZE)
|
|
printf("[CR_FILESIZE]");
|
|
else if (*t == CR_DEFINED)
|
|
printf("[CR_DEFINED]");
|
|
else if (*t == CR_REFERENCED)
|
|
printf("[CR_REFERENCED]");
|
|
else if (*t == CR_STREQ)
|
|
printf("[CR_STREQ]");
|
|
else if (*t == CR_MACDEF)
|
|
printf("[CR_MACDEF]");
|
|
else if (*t == CR_TIME)
|
|
printf("[CR_TIME]");
|
|
else if (*t == CR_DATE)
|
|
printf("[CR_DATE]");
|
|
else if (*t >= 0x20 && *t <= 0x2F)
|
|
printf("[%c]", (char)*t);
|
|
else if (*t >= 0x3A && *t <= 0x3F)
|
|
printf("[%c]", (char)*t);
|
|
else if (*t >= 0x80 && *t <= 0x87)
|
|
printf("[D%u]", ((uint32_t)*t) - 0x80);
|
|
else if (*t >= 0x88 && *t <= 0x8F)
|
|
printf("[A%u]", ((uint32_t)*t) - 0x88);
|
|
else
|
|
printf("[%X:%c]", (uint32_t)*t, (char)*t);
|
|
}
|
|
|
|
printf("[EOL]\n");
|
|
}
|
|
|
|
|
|
//
|
|
// Dump everything
|
|
//
|
|
int dump_everything(void)
|
|
{
|
|
// FFS
|
|
if ((currentorg[1] - currentorg[0]) == 0)
|
|
sect[M6502].sfcode = NULL;
|
|
|
|
for(int i=1; i<NSECTS; i++)
|
|
{
|
|
if (sect[i].scattr & SUSED)
|
|
{
|
|
printf("Section %d sloc=$%X\n", i, sect[i].sloc);
|
|
printf("Code:\n");
|
|
chdump(sect[i].sfcode, 1);
|
|
|
|
printf("Fixup:\n");
|
|
fudump(sect[i].sffix);
|
|
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
printf("\nMarks:\n");
|
|
mudump(); // Dump marks
|
|
|
|
return 0;
|
|
}
|
|
|