X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodegen.c;h=add409b1d6e5de9f7bd87d9d99e025594cbf2df6;hb=eab608616187b988e81e6f513fc405347ea620a7;hp=7830b099e9494bd304cbdd5b8bc308c28a6b1f01;hpb=2fead582431c9017cae8fb3c0289c248de5c9923;p=cc65 diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 7830b099e..add409b1d 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ +/* (C) 1998-2001 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -35,47 +35,41 @@ #include #include +#include /* common */ #include "check.h" #include "version.h" #include "xmalloc.h" +#include "xsprintf.h" /* cc65 */ #include "asmcode.h" #include "asmlabel.h" +#include "codeseg.h" #include "cpu.h" +#include "dataseg.h" #include "error.h" #include "global.h" -#include "litpool.h" -#include "optimize.h" -#include "segname.h" +#include "segments.h" #include "util.h" #include "codegen.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ -/* Compiler relative stk ptr */ +/* Compiler relative stack pointer */ int oursp = 0; -/* Current segment */ -segment_t CurSeg = SEG_INV; - -/* Segment names */ -static char* SegmentHints [4] = { - "seg:code", "seg:rodata", "seg:data", "seg:bss" -}; - /*****************************************************************************/ -/* Helpers */ +/* Helpers */ /*****************************************************************************/ @@ -93,7 +87,6 @@ static void CheckLocalOffs (unsigned Offs) { if (Offs >= 256) { /* Too many local vars */ - AddCodeLine (";*** Too many locals"); Error ("Too many local variables"); } } @@ -108,8 +101,8 @@ static char* GetLabelName (unsigned flags, unsigned long label, unsigned offs) switch (flags & CF_ADDRMASK) { case CF_STATIC: - /* Static memory cell */ - sprintf (lbuf, "L%04X+%u", (unsigned)(label & 0xFFFF), offs); + /* Static memory cell */ + sprintf (lbuf, "%s+%u", LocalLabelName (label), offs); break; case CF_EXTERNAL: @@ -138,7 +131,7 @@ static char* GetLabelName (unsigned flags, unsigned long label, unsigned offs) /*****************************************************************************/ -/* Pre- and postamble */ +/* Pre- and postamble */ /*****************************************************************************/ @@ -146,86 +139,62 @@ static char* GetLabelName (unsigned flags, unsigned long label, unsigned offs) void g_preamble (void) /* Generate the assembler code preamble */ { - AddCodeLine ("; File generated by cc65 v %u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH); - AddEmptyLine (); + /* Create a new segment list */ + PushSegments (0); + + /* Identify the compiler version */ + AddTextLine (";"); + AddTextLine ("; File generated by cc65 v %u.%u.%u", + VER_MAJOR, VER_MINOR, VER_PATCH); + AddTextLine (";"); /* Insert some object file options */ - AddCodeLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", VER_MAJOR, VER_MINOR, VER_PATCH); - AddEmptyLine (); + AddTextLine ("\t.fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", + VER_MAJOR, VER_MINOR, VER_PATCH); /* If we're producing code for some other CPU, switch the command set */ if (CPU == CPU_65C02) { - AddCodeLine (".pc02"); + AddTextLine ("\t.pc02"); } /* Allow auto import for runtime library routines */ - AddCodeLine (".autoimport\ton"); + AddTextLine ("\t.autoimport\ton"); /* Switch the assembler into case sensitive mode */ - AddCodeLine (".case\t\ton"); + AddTextLine ("\t.case\t\ton"); /* Tell the assembler if we want to generate debug info */ - AddCodeLine (".debuginfo\t%s", (DebugInfo != 0)? "on" : "off"); + AddTextLine ("\t.debuginfo\t%s", (DebugInfo != 0)? "on" : "off"); /* Import the stack pointer for direct auto variable access */ - AddCodeLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1"); + AddTextLine ("\t.importzp\tsp, sreg, regsave, regbank, tmp1, ptr1"); /* Define long branch macros */ - AddCodeLine (".macpack\tlongbranch"); - AddEmptyLine (); - - /* Define the ldax macro */ - AddCodeLine (".macro ldax Value"); - AddCodeLine (" lda #<(Value)"); - AddCodeLine (" ldx #>(Value)"); - AddCodeLine (".endmacro"); - AddEmptyLine (); - - /* Tell the optimizer that this is the end of the preamble */ - AddCodeHint ("end_of_preamble"); + AddTextLine ("\t.macpack\tlongbranch"); } -void g_postamble (void) -/* Generate assembler code postamble */ +void g_fileinfo (const char* Name, unsigned long Size, unsigned long MTime) +/* If debug info is enabled, place a file info into the source */ { - /* Tell the optimizer that this is the start of the postamble */ - AddCodeHint ("start_of_postamble"); + if (DebugInfo) { + AddTextLine ("\t.dbg\t\tfile, \"%s\", %lu, %lu", Name, Size, MTime); + } } /*****************************************************************************/ -/* Segment support */ +/* Segment support */ /*****************************************************************************/ -static void UseSeg (int NewSeg) -/* Switch to a specific segment */ -{ - if (CurSeg != NewSeg) { - CurSeg = (segment_t) NewSeg; - AddCodeLine (".segment\t\"%s\"", SegmentNames [CurSeg]); - AddCodeHint (SegmentHints [CurSeg]); - } -} - - - -void g_usecode (void) -/* Switch to the code segment */ -{ - UseSeg (SEG_CODE); -} - - - void g_userodata (void) /* Switch to the read only data segment */ { - UseSeg (SEG_RODATA); + UseDataSeg (SEG_RODATA); } @@ -233,7 +202,7 @@ void g_userodata (void) void g_usedata (void) /* Switch to the data segment */ { - UseSeg (SEG_DATA); + UseDataSeg (SEG_DATA); } @@ -241,62 +210,46 @@ void g_usedata (void) void g_usebss (void) /* Switch to the bss segment */ { - UseSeg (SEG_BSS); + UseDataSeg (SEG_BSS); } -static void SegName (segment_t Seg, const char* Name) -/* Set the name of a segment */ +static void OutputDataLine (DataSeg* S, const char* Format, ...) +/* Add a line to the current data segment */ { - /* Free the old name and set a new one */ - NewSegName (Seg, Name); - - /* If the new segment is the current segment, emit a segment directive - * with the new name. - */ - if (Seg == CurSeg) { - CurSeg = SEG_INV; /* Invalidate */ - UseSeg (Seg); - } + va_list ap; + va_start (ap, Format); + AddDataEntry (S, Format, ap); + va_end (ap); } -void g_codename (const char* Name) -/* Set the name of the CODE segment */ -{ - SegName (SEG_CODE, Name); -} - - - -void g_rodataname (const char* Name) -/* Set the name of the RODATA segment */ +void g_segname (segment_t Seg, const char* Name) +/* Set the name of a segment */ { - SegName (SEG_RODATA, Name); -} - - - -void g_dataname (const char* Name) -/* Set the name of the DATA segment */ -{ - SegName (SEG_DATA, Name); -} - + DataSeg* S; + /* Remember the new name */ + NewSegName (Seg, Name); -void g_bssname (const char* Name) -/* Set the name of the BSS segment */ -{ - SegName (SEG_BSS, Name); + /* Emit a segment directive for the data style segments */ + switch (Seg) { + case SEG_RODATA: S = CS->ROData; break; + case SEG_DATA: S = CS->Data; break; + case SEG_BSS: S = CS->BSS; break; + default: S = 0; break; + } + if (S) { + OutputDataLine (S, ".segment\t\"%s\"", Name); + } } /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -375,16 +328,24 @@ static unsigned MakeByteOffs (unsigned Flags, unsigned Offs) -void g_defloclabel (unsigned label) -/* Define a local label */ +void g_defcodelabel (unsigned label) +/* Define a local code label */ { - AddCodeLine ("L%04X:", label & 0xFFFF); + AddCodeLabel (CS->Code, LocalLabelName (label)); +} + + + +void g_defdatalabel (unsigned label) +/* Define a local data label */ +{ + AddDataLine ("%s:", LocalLabelName (label)); } /*****************************************************************************/ -/* Functions handling global labels */ +/* Functions handling global labels */ /*****************************************************************************/ @@ -392,7 +353,8 @@ void g_defloclabel (unsigned label) void g_defgloblabel (const char* Name) /* Define a global label with the given name */ { - AddCodeLine ("_%s:", Name); + /* Global labels are always data labels */ + AddDataLine ("_%s:", Name); } @@ -401,9 +363,9 @@ void g_defexport (const char* Name, int ZP) /* Export the given label */ { if (ZP) { - AddCodeLine ("\t.exportzp\t_%s", Name); + AddTextLine ("\t.exportzp\t_%s", Name); } else { - AddCodeLine ("\t.export\t\t_%s", Name); + AddTextLine ("\t.export\t\t_%s", Name); } } @@ -413,9 +375,9 @@ void g_defimport (const char* Name, int ZP) /* Import the given label */ { if (ZP) { - AddCodeLine ("\t.importzp\t_%s", Name); + AddTextLine ("\t.importzp\t_%s", Name); } else { - AddCodeLine ("\t.import\t\t_%s", Name); + AddTextLine ("\t.import\t\t_%s", Name); } } @@ -430,7 +392,7 @@ void g_defimport (const char* Name, int ZP) static void ldaconst (unsigned val) /* Load a with a constant */ { - AddCodeLine ("\tlda\t#$%02X", val & 0xFF); + AddCodeLine ("lda #$%02X", val & 0xFF); } @@ -438,7 +400,7 @@ static void ldaconst (unsigned val) static void ldxconst (unsigned val) /* Load x with a constant */ { - AddCodeLine ("\tldx\t#$%02X", val & 0xFF); + AddCodeLine ("ldx #$%02X", val & 0xFF); } @@ -446,7 +408,7 @@ static void ldxconst (unsigned val) static void ldyconst (unsigned val) /* Load y with a constant */ { - AddCodeLine ("\tldy\t#$%02X", val & 0xFF); + AddCodeLine ("ldy #$%02X", val & 0xFF); } @@ -473,86 +435,47 @@ void g_enter (unsigned flags, unsigned argsize) funcargs = argsize; } else { funcargs = -1; - AddCodeLine ("\tjsr\tenter"); + AddCodeLine ("jsr enter"); } } -void g_leave (int flags, int val) +void g_leave (void) /* Function epilogue */ { - int k; - char buf [40]; - - /* CF_REG is set if we're returning a value from the function */ - if ((flags & CF_REG) == 0) { - AddCodeHint ("x:-"); - AddCodeHint ("a:-"); - } - /* How many bytes of locals do we have to drop? */ - k = -oursp; + int k = -oursp; /* If we didn't have a variable argument list, don't call leave */ if (funcargs >= 0) { - /* Load a function return code if needed */ - if ((flags & CF_CONST) != 0) { - g_getimmed (flags, val, 0); - } - - /* Drop stackframe or leave with rts */ + /* Drop stackframe if needed */ k += funcargs; - if (k == 0) { - AddCodeHint ("y:-"); /* Y register no longer used */ - AddCodeLine ("\trts"); - } else if (k <= 8) { - AddCodeHint ("y:-"); /* Y register no longer used */ - AddCodeLine ("\tjmp\tincsp%d", k); - } else { - CheckLocalOffs (k); - ldyconst (k); - AddCodeLine ("\tjmp\taddysp"); + if (k > 0) { + if (k <= 8) { + AddCodeLine ("jsr incsp%d", k); + } else { + CheckLocalOffs (k); + ldyconst (k); + AddCodeLine ("jsr addysp"); + } } } else { - strcpy (buf, "\tjmp\tleave"); - if (k) { + if (k == 0) { + /* Nothing to drop */ + AddCodeLine ("jsr leave"); + } else { /* We've a stack frame to drop */ ldyconst (k); - strcat (buf, "y"); - } else { - /* Y register no longer used */ - AddCodeHint ("y:-"); + AddCodeLine ("jsr leavey"); } - if (flags & CF_CONST) { - if ((flags & CF_TYPE) != CF_LONG) { - /* Constant int sized value given for return code */ - if (val == 0) { - /* Special case: return 0 */ - strcat (buf, "00"); - } else if (((val >> 8) & 0xFF) == 0) { - /* Special case: constant with high byte zero */ - ldaconst (val); /* Load low byte */ - strcat (buf, "0"); - } else { - /* Others: arbitrary constant value */ - g_getimmed (flags, val, 0); /* Load value */ - } - } else { - /* Constant long value: No shortcut possible */ - g_getimmed (flags, val, 0); - } - } - - /* Output the jump */ - AddCodeLine (buf); } - /* Add an empty line after a function to make the code more readable */ - AddEmptyLine (); + /* Add the final rts */ + AddCodeLine ("rts"); } @@ -569,28 +492,28 @@ void g_save_regvars (int RegOffs, unsigned Bytes) /* Don't loop for up to two bytes */ if (Bytes == 1) { - AddCodeLine ("\tlda\tregbank%+d", RegOffs); - AddCodeLine ("\tjsr\tpusha"); + AddCodeLine ("lda regbank%+d", RegOffs); + AddCodeLine ("jsr pusha"); } else if (Bytes == 2) { - AddCodeLine ("\tlda\tregbank%+d", RegOffs); - AddCodeLine ("\tldx\tregbank%+d", RegOffs+1); - AddCodeLine ("\tjsr\tpushax"); + AddCodeLine ("lda regbank%+d", RegOffs); + AddCodeLine ("ldx regbank%+d", RegOffs+1); + AddCodeLine ("jsr pushax"); } else { /* More than two bytes - loop */ - unsigned Label = GetLabel (); + unsigned Label = GetLocalLabel (); g_space (Bytes); ldyconst (Bytes - 1); ldxconst (Bytes); - g_defloclabel (Label); - AddCodeLine ("\tlda\tregbank%+d,x", RegOffs-1); - AddCodeLine ("\tsta\t(sp),y"); - AddCodeLine ("\tdey"); - AddCodeLine ("\tdex"); - AddCodeLine ("\tbne\tL%04X", Label); + g_defcodelabel (Label); + AddCodeLine ("lda regbank%+d,x", RegOffs-1); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("dey"); + AddCodeLine ("dex"); + AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -611,30 +534,30 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) if (Bytes == 1) { ldyconst (StackOffs); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsta\tregbank%+d", RegOffs); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d", RegOffs); } else if (Bytes == 2) { ldyconst (StackOffs); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsta\tregbank%+d", RegOffs); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsta\tregbank%+d", RegOffs+1); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d", RegOffs); + AddCodeLine ("iny"); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d", RegOffs+1); } else { /* More than two bytes - loop */ - unsigned Label = GetLabel (); + unsigned Label = GetLocalLabel (); ldyconst (StackOffs+Bytes-1); ldxconst (Bytes); - g_defloclabel (Label); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsta\tregbank%+d,x", RegOffs-1); - AddCodeLine ("\tdey"); - AddCodeLine ("\tdex"); - AddCodeLine ("\tbne\tL%04X", Label); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d,x", RegOffs-1); + AddCodeLine ("dey"); + AddCodeLine ("dex"); + AddCodeLine ("bne %s", LocalLabelName (Label)); } } @@ -647,65 +570,74 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) -void g_getimmed (unsigned flags, unsigned long val, unsigned offs) +void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs) /* Load a constant into the primary register */ { - if ((flags & CF_CONST) != 0) { + unsigned char B1, B2, B3, B4; + unsigned Done; + + + if ((Flags & CF_CONST) != 0) { /* Numeric constant */ - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: - if ((flags & CF_FORCECHAR) != 0) { - ldaconst (val); + if ((Flags & CF_FORCECHAR) != 0) { + ldaconst (Val); break; } /* FALL THROUGH */ case CF_INT: - ldxconst ((val >> 8) & 0xFF); - ldaconst (val & 0xFF); + ldxconst ((Val >> 8) & 0xFF); + ldaconst (Val & 0xFF); break; case CF_LONG: - if (val < 0x100) { - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tstx\tsreg+1"); - AddCodeLine ("\tstx\tsreg"); - AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); - } else if ((val & 0xFFFF00FF) == 0) { - AddCodeLine ("\tlda\t#$00"); - AddCodeLine ("\tsta\tsreg+1"); - AddCodeLine ("\tsta\tsreg"); - AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); - } else if ((val & 0xFFFF0000) == 0 && CodeSizeFactor > 140) { - AddCodeLine ("\tlda\t#$00"); - AddCodeLine ("\tsta\tsreg+1"); - AddCodeLine ("\tsta\tsreg"); - AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); - AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); - } else if ((val & 0xFFFFFF00) == 0xFFFFFF00) { - AddCodeLine ("\tldx\t#$FF"); - AddCodeLine ("\tstx\tsreg+1"); - AddCodeLine ("\tstx\tsreg"); - if ((val & 0xFF) == 0xFF) { - AddCodeLine ("\ttxa"); - } else { - AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); - } - } else if ((val & 0xFFFF00FF) == 0xFFFF00FF) { - AddCodeLine ("\tlda\t#$FF"); - AddCodeLine ("\tsta\tsreg+1"); - AddCodeLine ("\tsta\tsreg"); - AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); - } else { - /* Call a subroutine that will load following value */ - AddCodeLine ("\tjsr\tldeax"); - AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF); - } + /* Split the value into 4 bytes */ + B1 = (unsigned char) (Val >> 0); + B2 = (unsigned char) (Val >> 8); + B3 = (unsigned char) (Val >> 16); + B4 = (unsigned char) (Val >> 24); + + /* Remember which bytes are done */ + Done = 0; + + /* Load the value */ + AddCodeLine ("ldx #$%02X", B2); + Done |= 0x02; + if (B2 == B3) { + AddCodeLine ("stx sreg"); + Done |= 0x04; + } + if (B2 == B4) { + AddCodeLine ("stx sreg+1"); + Done |= 0x08; + } + if ((Done & 0x04) == 0 && B1 != B3) { + AddCodeLine ("lda #$%02X", B3); + AddCodeLine ("sta sreg"); + Done |= 0x04; + } + if ((Done & 0x08) == 0 && B1 != B4) { + AddCodeLine ("lda #$%02X", B4); + AddCodeLine ("sta sreg+1"); + Done |= 0x08; + } + AddCodeLine ("lda #$%02X", B1); + Done |= 0x01; + if ((Done & 0x04) == 0) { + CHECK (B1 == B3); + AddCodeLine ("sta sreg"); + } + if ((Done & 0x08) == 0) { + CHECK (B1 == B4); + AddCodeLine ("sta sreg+1"); + } break; default: - typeerror (flags); + typeerror (Flags); break; } @@ -713,10 +645,11 @@ void g_getimmed (unsigned flags, unsigned long val, unsigned offs) } else { /* Some sort of label */ - const char* Label = GetLabelName (flags, val, offs); + const char* Label = GetLabelName (Flags, Val, Offs); /* Load the address into the primary */ - AddCodeLine ("\tldax\t%s", Label); + AddCodeLine ("lda #<(%s)", Label); + AddCodeLine ("ldx #>(%s)", Label); } } @@ -734,41 +667,42 @@ void g_getstatic (unsigned flags, unsigned long label, unsigned offs) case CF_CHAR: if ((flags & CF_FORCECHAR) || (flags & CF_TEST)) { - AddCodeLine ("\tlda\t%s", lbuf); /* load A from the label */ + AddCodeLine ("lda %s", lbuf); /* load A from the label */ } else { ldxconst (0); - AddCodeLine ("\tlda\t%s", lbuf); /* load A from the label */ + AddCodeLine ("lda %s", lbuf); /* load A from the label */ if (!(flags & CF_UNSIGNED)) { /* Must sign extend */ - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* X is invalid now */ + unsigned L = GetLocalLabel (); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } } break; case CF_INT: - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("lda %s", lbuf); if (flags & CF_TEST) { - AddCodeLine ("\tora\t%s+1", lbuf); + AddCodeLine ("ora %s+1", lbuf); } else { - AddCodeLine ("\tldx\t%s+1", lbuf); + AddCodeLine ("ldx %s+1", lbuf); } break; case CF_LONG: if (flags & CF_TEST) { - AddCodeLine ("\tlda\t%s+3", lbuf); - AddCodeLine ("\tora\t%s+2", lbuf); - AddCodeLine ("\tora\t%s+1", lbuf); - AddCodeLine ("\tora\t%s+0", lbuf); + AddCodeLine ("lda %s+3", lbuf); + AddCodeLine ("ora %s+2", lbuf); + AddCodeLine ("ora %s+1", lbuf); + AddCodeLine ("ora %s+0", lbuf); } else { - AddCodeLine ("\tlda\t%s+3", lbuf); - AddCodeLine ("\tsta\tsreg+1"); - AddCodeLine ("\tlda\t%s+2", lbuf); - AddCodeLine ("\tsta\tsreg"); - AddCodeLine ("\tldx\t%s+1", lbuf); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("lda %s+3", lbuf); + AddCodeLine ("sta sreg+1"); + AddCodeLine ("lda %s+2", lbuf); + AddCodeLine ("sta sreg"); + AddCodeLine ("ldx %s+1", lbuf); + AddCodeLine ("lda %s", lbuf); } break; @@ -790,24 +724,20 @@ void g_getlocal (unsigned flags, int offs) case CF_CHAR: if ((flags & CF_FORCECHAR) || (flags & CF_TEST)) { if (CPU == CPU_65C02 && offs == 0) { - AddCodeLine ("\tlda\t(sp)"); + AddCodeLine ("lda (sp)"); } else { ldyconst (offs); - AddCodeLine ("\tlda\t(sp),y"); + AddCodeLine ("lda (sp),y"); } } else { - if (offs == 0) { - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t(sp,x)"); - } else { - ldyconst (offs); - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t(sp),y"); - } + ldyconst (offs); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda (sp),y"); if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* X is invalid now */ + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } } break; @@ -816,22 +746,22 @@ void g_getlocal (unsigned flags, int offs) CheckLocalOffs (offs + 1); if (flags & CF_TEST) { ldyconst (offs + 1); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tdey"); - AddCodeLine ("\tora\t(sp),y"); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("dey"); + AddCodeLine ("ora (sp),y"); } else { if (CodeSizeFactor > 180) { ldyconst (offs + 1); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tdey"); - AddCodeLine ("\tlda\t(sp),y"); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("tax"); + AddCodeLine ("dey"); + AddCodeLine ("lda (sp),y"); } else { if (offs) { ldyconst (offs+1); - AddCodeLine ("\tjsr\tldaxysp"); + AddCodeLine ("jsr ldaxysp"); } else { - AddCodeLine ("\tjsr\tldax0sp"); + AddCodeLine ("jsr ldax0sp"); } } } @@ -840,11 +770,11 @@ void g_getlocal (unsigned flags, int offs) case CF_LONG: if (offs) { ldyconst (offs+3); - AddCodeLine ("\tjsr\tldeaxysp"); + AddCodeLine ("jsr ldeaxysp"); } else { - AddCodeLine ("\tjsr\tldeax0sp"); + AddCodeLine ("jsr ldeax0sp"); } - break; + break; default: typeerror (flags); @@ -872,22 +802,23 @@ void g_getind (unsigned flags, unsigned offs) if (offs) { ldyconst (offs); if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tldauidx"); + AddCodeLine ("jsr ldauidx"); } else { - AddCodeLine ("\tjsr\tldaidx"); + AddCodeLine ("jsr ldaidx"); } } else { if (flags & CF_UNSIGNED) { - if (CodeSizeFactor > 250) { - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t(ptr1,x)"); + if (CodeSizeFactor > 330) { + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$00"); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda (ptr1),y"); } else { - AddCodeLine ("\tjsr\tldaui"); + AddCodeLine ("jsr ldaui"); } } else { - AddCodeLine ("\tjsr\tldai"); + AddCodeLine ("jsr ldai"); } } break; @@ -895,30 +826,30 @@ void g_getind (unsigned flags, unsigned offs) case CF_INT: if (flags & CF_TEST) { ldyconst (offs); - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - AddCodeLine ("\tlda\t(ptr1),y"); - AddCodeLine ("\tiny"); - AddCodeLine ("\tora\t(ptr1),y"); + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("iny"); + AddCodeLine ("ora (ptr1),y"); } else { if (offs == 0) { - AddCodeLine ("\tjsr\tldaxi"); + AddCodeLine ("jsr ldaxi"); } else { ldyconst (offs+1); - AddCodeLine ("\tjsr\tldaxidx"); + AddCodeLine ("jsr ldaxidx"); } } break; case CF_LONG: if (offs == 0) { - AddCodeLine ("\tjsr\tldeaxi"); + AddCodeLine ("jsr ldeaxi"); } else { ldyconst (offs+3); - AddCodeLine ("\tjsr\tldeaxidx"); + AddCodeLine ("jsr ldeaxidx"); } if (flags & CF_TEST) { - AddCodeLine ("\tjsr\ttsteax"); + AddCodeLine ("jsr tsteax"); } break; @@ -938,30 +869,30 @@ void g_leasp (int offs) /* For value 0 we do direct code */ if (offs == 0) { - AddCodeLine ("\tlda\tsp"); - AddCodeLine ("\tldx\tsp+1"); + AddCodeLine ("lda sp"); + AddCodeLine ("ldx sp+1"); } else { - if (CodeSizeFactor < 300) { - ldaconst (offs); /* Load A with offset value */ - AddCodeLine ("\tjsr\tleaasp"); /* Load effective address */ - } else { - if (CPU == CPU_65C02 && offs == 1) { - AddCodeLine ("\tlda\tsp"); - AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tina"); - AddCodeLine ("\tbne\t*+3"); - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); /* Invalidate X */ - } else { - ldaconst (offs); - AddCodeLine ("\tclc"); - AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tadc\tsp"); - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); /* Invalidate X */ - } - } + if (CodeSizeFactor < 300) { + ldaconst (offs); /* Load A with offset value */ + AddCodeLine ("jsr leaasp"); /* Load effective address */ + } else { + unsigned L = GetLocalLabel (); + if (CPU == CPU_65C02 && offs == 1) { + AddCodeLine ("lda sp"); + AddCodeLine ("ldx sp+1"); + AddCodeLine ("ina"); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("inx"); + } else { + ldaconst (offs); + AddCodeLine ("clc"); + AddCodeLine ("ldx sp+1"); + AddCodeLine ("adc sp"); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + } + g_defcodelabel (L); + } } } @@ -984,61 +915,33 @@ void g_leavariadic (int Offs) ArgSizeOffs = -oursp; CheckLocalOffs (ArgSizeOffs); - /* Get the stack pointer plus offset. Clear the carry as the result of - * this sequence. - */ - if (Offs > 0) { - AddCodeLine ("\tclc"); - AddCodeLine ("\tlda\tsp"); - AddCodeLine ("\tadc\t#$%02X", Offs & 0xFF); - if (Offs >= 256) { - AddCodeLine ("\tpha"); - AddCodeLine ("\tlda\tsp+1"); - AddCodeLine ("\tadc\t#$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); - AddCodeLine ("\tclc"); - } else { - AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tbcc\t*+4"); /* Jump over the clc */ - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); /* Invalidate X */ - AddCodeLine ("\tclc"); - } - } else if (Offs < 0) { - Offs = -Offs; - AddCodeLine ("\tsec"); - AddCodeLine ("\tlda\tsp"); - AddCodeLine ("\tsbc\t#$%02X", Offs & 0xFF); - if (Offs >= 256) { - AddCodeLine ("\tpha"); - AddCodeLine ("\tlda\tsp+1"); - AddCodeLine ("\tsbc\t#$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); - } else { - AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tbcs\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* Invalidate X */ - } - AddCodeLine ("\tclc"); + /* Get the size of all parameters. */ + if (ArgSizeOffs == 0 && CPU == CPU_65C02) { + AddCodeLine ("lda (sp)"); + } else { + ldyconst (ArgSizeOffs); + AddCodeLine ("lda (sp),y"); + } + + /* Add the value of the stackpointer */ + if (CodeSizeFactor > 250) { + unsigned L = GetLocalLabel(); + AddCodeLine ("ldx sp+1"); + AddCodeLine ("clc"); + AddCodeLine ("adc sp"); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + g_defcodelabel (L); } else { - AddCodeLine ("\tlda\tsp"); - AddCodeLine ("\tldx\tsp+1"); - AddCodeLine ("\tclc"); + AddCodeLine ("jsr leaasp"); } - /* Add the size of all parameters. Carry is clear on entry. */ - if (ArgSizeOffs == 0 && CPU == CPU_65C02) { - AddCodeLine ("\tadc\t(sp)"); - } else { - ldyconst (ArgSizeOffs); - AddCodeLine ("\tadc\t(sp),y"); + /* Add the offset to the primary */ + if (Offs > 0) { + g_inc (CF_INT | CF_CONST, Offs); + } else if (Offs < 0) { + g_dec (CF_INT | CF_CONST, -Offs); } - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); /* Invalidate X */ } @@ -1059,21 +962,21 @@ void g_putstatic (unsigned flags, unsigned long label, unsigned offs) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("sta %s", lbuf); break; case CF_INT: - AddCodeLine ("\tsta\t%s", lbuf); - AddCodeLine ("\tstx\t%s+1", lbuf); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("stx %s+1", lbuf); break; case CF_LONG: - AddCodeLine ("\tsta\t%s", lbuf); - AddCodeLine ("\tstx\t%s+1", lbuf); - AddCodeLine ("\tldy\tsreg"); - AddCodeLine ("\tsty\t%s+2", lbuf); - AddCodeLine ("\tldy\tsreg+1"); - AddCodeLine ("\tsty\t%s+3", lbuf); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("stx %s+1", lbuf); + AddCodeLine ("ldy sreg"); + AddCodeLine ("sty %s+2", lbuf); + AddCodeLine ("ldy sreg+1"); + AddCodeLine ("sty %s+3", lbuf); break; default: @@ -1093,59 +996,59 @@ void g_putlocal (unsigned Flags, int Offs, long Val) case CF_CHAR: if (Flags & CF_CONST) { - AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val); + AddCodeLine ("lda #$%02X", (unsigned char) Val); } if (CPU == CPU_65C02 && Offs == 0) { - AddCodeLine ("\tsta\t(sp)"); + AddCodeLine ("sta (sp)"); } else { ldyconst (Offs); - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("sta (sp),y"); } break; case CF_INT: if (Flags & CF_CONST) { ldyconst (Offs+1); - AddCodeLine ("\tlda\t#$%02X", (unsigned char) (Val >> 8)); - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("lda #$%02X", (unsigned char) (Val >> 8)); + AddCodeLine ("sta (sp),y"); if ((Flags & CF_NOKEEP) == 0) { /* Place high byte into X */ - AddCodeLine ("\ttax"); + AddCodeLine ("tax"); } if (CPU == CPU_65C02 && Offs == 0) { - AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val); - AddCodeLine ("\tsta\t(sp)"); + AddCodeLine ("lda #$%02X", (unsigned char) Val); + AddCodeLine ("sta (sp)"); } else { if ((Val & 0xFF) == Offs+1) { /* The value we need is already in Y */ - AddCodeLine ("\ttya"); - AddCodeLine ("\tdey"); + AddCodeLine ("tya"); + AddCodeLine ("dey"); } else { - AddCodeLine ("\tdey"); - AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val); + AddCodeLine ("dey"); + AddCodeLine ("lda #$%02X", (unsigned char) Val); } - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("sta (sp),y"); } } else { if ((Flags & CF_NOKEEP) == 0 || CodeSizeFactor < 160) { if (Offs) { ldyconst (Offs); - AddCodeLine ("\tjsr\tstaxysp"); + AddCodeLine ("jsr staxysp"); } else { - AddCodeLine ("\tjsr\tstax0sp"); + AddCodeLine ("jsr stax0sp"); } } else { if (CPU == CPU_65C02 && Offs == 0) { - AddCodeLine ("\tsta\t(sp)"); + AddCodeLine ("sta (sp)"); ldyconst (1); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("txa"); + AddCodeLine ("sta (sp),y"); } else { ldyconst (Offs); - AddCodeLine ("\tsta\t(sp),y"); - AddCodeLine ("\tiny"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("iny"); + AddCodeLine ("txa"); + AddCodeLine ("sta (sp),y"); } } } @@ -1157,9 +1060,9 @@ void g_putlocal (unsigned Flags, int Offs, long Val) } if (Offs) { ldyconst (Offs); - AddCodeLine ("\tjsr\tsteaxysp"); + AddCodeLine ("jsr steaxysp"); } else { - AddCodeLine ("\tjsr\tsteax0sp"); + AddCodeLine ("jsr steax0sp"); } break; @@ -1184,17 +1087,17 @@ void g_putind (unsigned Flags, unsigned Offs) if ((Offs & 0xFF) > 256 - sizeofarg (Flags | CF_FORCECHAR)) { /* Overflow - we need to add the low byte also */ - AddCodeLine ("\tldy\t#$00"); - AddCodeLine ("\tclc"); - AddCodeLine ("\tpha"); - AddCodeLine ("\tlda\t#$%02X", Offs & 0xFF); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tsta\t(sp),y"); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t#$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tsta\t(sp),y"); - AddCodeLine ("\tpla"); + AddCodeLine ("ldy #$00"); + AddCodeLine ("clc"); + AddCodeLine ("pha"); + AddCodeLine ("lda #$%02X", Offs & 0xFF); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("iny"); + AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("pla"); /* Complete address is on stack, new offset is zero */ Offs = 0; @@ -1202,13 +1105,13 @@ void g_putind (unsigned Flags, unsigned Offs) } else if ((Offs & 0xFF00) != 0) { /* We can just add the high byte */ - AddCodeLine ("\tldy\t#$01"); - AddCodeLine ("\tclc"); - AddCodeLine ("\tpha"); - AddCodeLine ("\tlda\t#$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tsta\t(sp),y"); - AddCodeLine ("\tpla"); + AddCodeLine ("ldy #$01"); + AddCodeLine ("clc"); + AddCodeLine ("pha"); + AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("pla"); /* Offset is now just the low byte */ Offs &= 0x00FF; @@ -1220,27 +1123,27 @@ void g_putind (unsigned Flags, unsigned Offs) case CF_CHAR: if (Offs) { ldyconst (Offs); - AddCodeLine ("\tjsr\tstaspidx"); + AddCodeLine ("jsr staspidx"); } else { - AddCodeLine ("\tjsr\tstaspp"); + AddCodeLine ("jsr staspp"); } break; case CF_INT: if (Offs) { ldyconst (Offs); - AddCodeLine ("\tjsr\tstaxspidx"); + AddCodeLine ("jsr staxspidx"); } else { - AddCodeLine ("\tjsr\tstaxspp"); + AddCodeLine ("jsr staxspp"); } break; case CF_LONG: if (Offs) { ldyconst (Offs); - AddCodeLine ("\tjsr\tsteaxspidx"); + AddCodeLine ("jsr steaxspidx"); } else { - AddCodeLine ("\tjsr\tsteaxspp"); + AddCodeLine ("jsr steaxspp"); } break; @@ -1269,9 +1172,9 @@ void g_toslong (unsigned flags) case CF_CHAR: case CF_INT: if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\ttosulong"); + AddCodeLine ("jsr tosulong"); } else { - AddCodeLine ("\tjsr\ttoslong"); + AddCodeLine ("jsr toslong"); } push (CF_INT); break; @@ -1296,7 +1199,7 @@ void g_tosint (unsigned flags) break; case CF_LONG: - AddCodeLine ("\tjsr\ttosint"); + AddCodeLine ("jsr tosint"); pop (CF_INT); break; @@ -1317,13 +1220,13 @@ void g_reglong (unsigned flags) if (flags & CF_UNSIGNED) { if (CodeSizeFactor >= 200) { ldyconst (0); - AddCodeLine ("\tsty\tsreg"); - AddCodeLine ("\tsty\tsreg+1"); + AddCodeLine ("sty sreg"); + AddCodeLine ("sty sreg+1"); } else { - AddCodeLine ("\tjsr\taxulong"); + AddCodeLine ("jsr axulong"); } } else { - AddCodeLine ("\tjsr\taxlong"); + AddCodeLine ("jsr axlong"); } break; @@ -1444,7 +1347,7 @@ void g_scale (unsigned flags, long val) case CF_CHAR: if (flags & CF_FORCECHAR) { while (p2--) { - AddCodeLine ("\tasl\ta"); + AddCodeLine ("asl a"); } break; } @@ -1452,26 +1355,26 @@ void g_scale (unsigned flags, long val) case CF_INT: if (CodeSizeFactor >= (p2+1)*130U) { - AddCodeLine ("\tstx\ttmp1"); + AddCodeLine ("stx tmp1"); while (p2--) { - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\trol\ttmp1"); + AddCodeLine ("asl a"); + AddCodeLine ("rol tmp1"); } - AddCodeLine ("\tldx\ttmp1"); + AddCodeLine ("ldx tmp1"); } else { if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshlax%d", p2); + AddCodeLine ("jsr shlax%d", p2); } else { - AddCodeLine ("\tjsr\taslax%d", p2); + AddCodeLine ("jsr aslax%d", p2); } } break; case CF_LONG: if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshleax%d", p2); + AddCodeLine ("jsr shleax%d", p2); } else { - AddCodeLine ("\tjsr\tasleax%d", p2); + AddCodeLine ("jsr asleax%d", p2); } break; @@ -1500,12 +1403,12 @@ void g_scale (unsigned flags, long val) if (flags & CF_FORCECHAR) { if (flags & CF_UNSIGNED) { while (p2--) { - AddCodeLine ("\tlsr\ta"); + AddCodeLine ("lsr a"); } break; } else if (p2 <= 2) { - AddCodeLine ("\tcmp\t#$80"); - AddCodeLine ("\tror\ta"); + AddCodeLine ("cmp #$80"); + AddCodeLine ("ror a"); break; } } @@ -1514,35 +1417,35 @@ void g_scale (unsigned flags, long val) case CF_INT: if (flags & CF_UNSIGNED) { if (CodeSizeFactor >= (p2+1)*130U) { - AddCodeLine ("\tstx\ttmp1"); + AddCodeLine ("stx tmp1"); while (p2--) { - AddCodeLine ("\tlsr\ttmp1"); - AddCodeLine ("\tror\ta"); + AddCodeLine ("lsr tmp1"); + AddCodeLine ("ror a"); } - AddCodeLine ("\tldx\ttmp1"); + AddCodeLine ("ldx tmp1"); } else { - AddCodeLine ("\tjsr\tlsrax%d", p2); + AddCodeLine ("jsr lsrax%d", p2); } } else { if (CodeSizeFactor >= (p2+1)*150U) { - AddCodeLine ("\tstx\ttmp1"); + AddCodeLine ("stx tmp1"); while (p2--) { - AddCodeLine ("\tcpx\t#$80"); - AddCodeLine ("\tror\ttmp1"); - AddCodeLine ("\tror\ta"); + AddCodeLine ("cpx #$80"); + AddCodeLine ("ror tmp1"); + AddCodeLine ("ror a"); } - AddCodeLine ("\tldx\ttmp1"); + AddCodeLine ("ldx tmp1"); } else { - AddCodeLine ("\tjsr\tasrax%d", p2); + AddCodeLine ("jsr asrax%d", p2); } } break; case CF_LONG: if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tlsreax%d", p2); + AddCodeLine ("jsr lsreax%d", p2); } else { - AddCodeLine ("\tjsr\tasreax%d", p2); + AddCodeLine ("jsr asreax%d", p2); } break; @@ -1571,6 +1474,8 @@ void g_scale (unsigned flags, long val) void g_addlocal (unsigned flags, int offs) /* Add a local variable to ax */ { + unsigned L; + /* Correct the offset and check it */ offs -= oursp; CheckLocalOffs (offs); @@ -1578,24 +1483,25 @@ void g_addlocal (unsigned flags, int offs) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tldy\t#$%02X", offs & 0xFF); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); + L = GetLocalLabel(); + AddCodeLine ("ldy #$%02X", offs & 0xFF); + AddCodeLine ("clc"); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + g_defcodelabel (L); break; case CF_INT: - AddCodeLine ("\tldy\t#$%02X", offs & 0xFF); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tpha"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tiny"); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); + AddCodeLine ("ldy #$%02X", offs & 0xFF); + AddCodeLine ("clc"); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("pha"); + AddCodeLine ("txa"); + AddCodeLine ("iny"); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("tax"); + AddCodeLine ("pla"); break; case CF_LONG: @@ -1616,27 +1522,30 @@ void g_addlocal (unsigned flags, int offs) void g_addstatic (unsigned flags, unsigned long label, unsigned offs) /* Add a static variable to ax */ { + unsigned L; + /* Create the correct label name */ char* lbuf = GetLabelName (flags, label, offs); switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); + L = GetLocalLabel(); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + g_defcodelabel (L); break; case CF_INT: - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\ttay"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tadc\t%s+1", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("adc %s+1", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("tya"); break; case CF_LONG: @@ -1694,26 +1603,27 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs, case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tldx\t#$00"); + AddCodeLine ("ldx #$00"); if (flags & CF_CONST) { if (val == 1) { - AddCodeLine ("\tinc\t%s", lbuf); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("inc %s", lbuf); + AddCodeLine ("lda %s", lbuf); } else { - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("sta %s", lbuf); } } else { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("sta %s", lbuf); } if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* Invalidate X */ + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } break; } @@ -1722,55 +1632,55 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs, case CF_INT: if (flags & CF_CONST) { if (val == 1) { - label = GetLabel (); - AddCodeLine ("\tinc\t%s", lbuf); - AddCodeLine ("\tbne\tL%04X", (int)label); - AddCodeLine ("\tinc\t%s+1", lbuf); - g_defloclabel (label); - AddCodeLine ("\tlda\t%s", lbuf); /* Hmmm... */ - AddCodeLine ("\tldx\t%s+1", lbuf); + unsigned L = GetLocalLabel (); + AddCodeLine ("inc %s", lbuf); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("inc %s+1", lbuf); + g_defcodelabel (L); + AddCodeLine ("lda %s", lbuf); /* Hmmm... */ + AddCodeLine ("ldx %s+1", lbuf); } else { - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("sta %s", lbuf); if (val < 0x100) { - label = GetLabel (); - AddCodeLine ("\tbcc\tL%04X", (int)label); - AddCodeLine ("\tinc\t%s+1", lbuf); - g_defloclabel (label); - AddCodeLine ("\tldx\t%s+1", lbuf); + unsigned L = GetLocalLabel (); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inc %s+1", lbuf); + g_defcodelabel (L); + AddCodeLine ("ldx %s+1", lbuf); } else { - AddCodeLine ("\tlda\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tadc\t%s+1", lbuf); - AddCodeLine ("\tsta\t%s+1", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("lda #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("adc %s+1", lbuf); + AddCodeLine ("sta %s+1", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); } } } else { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t%s", lbuf); - AddCodeLine ("\tsta\t%s", lbuf); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tadc\t%s+1", lbuf); - AddCodeLine ("\tsta\t%s+1", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("clc"); + AddCodeLine ("adc %s", lbuf); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("txa"); + AddCodeLine ("adc %s+1", lbuf); + AddCodeLine ("sta %s+1", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); } break; case CF_LONG: if (flags & CF_CONST) { if (val < 0x100) { - AddCodeLine ("\tldy\t#<(%s)", lbuf); - AddCodeLine ("\tsty\tptr1"); - AddCodeLine ("\tldy\t#>(%s+1)", lbuf); + AddCodeLine ("ldy #<(%s)", lbuf); + AddCodeLine ("sty ptr1"); + AddCodeLine ("ldy #>(%s+1)", lbuf); if (val == 1) { - AddCodeLine ("\tjsr\tladdeq1"); + AddCodeLine ("jsr laddeq1"); } else { - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tjsr\tladdeqa"); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("jsr laddeqa"); } } else { g_getstatic (flags, label, offs); @@ -1778,10 +1688,10 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs, g_putstatic (flags, label, offs); } } else { - AddCodeLine ("\tldy\t#<(%s)", lbuf); - AddCodeLine ("\tsty\tptr1"); - AddCodeLine ("\tldy\t#>(%s+1)", lbuf); - AddCodeLine ("\tjsr\tladdeq"); + AddCodeLine ("ldy #<(%s)", lbuf); + AddCodeLine ("sty ptr1"); + AddCodeLine ("ldy #>(%s+1)", lbuf); + AddCodeLine ("jsr laddeq"); } break; @@ -1804,36 +1714,23 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - if (offs == 0) { - AddCodeLine ("\tldx\t#$00"); - if (flags & CF_CONST) { - AddCodeLine ("\tclc"); - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tadc\t(sp,x)"); - AddCodeLine ("\tsta\t(sp,x)"); - } else { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(sp,x)"); - AddCodeLine ("\tsta\t(sp,x)"); - } - } else { - ldyconst (offs); - AddCodeLine ("\tldx\t#$00"); - if (flags & CF_CONST) { - AddCodeLine ("\tclc"); - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tsta\t(sp),y"); - } else { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(sp),y"); - AddCodeLine ("\tsta\t(sp),y"); - } - } + ldyconst (offs); + AddCodeLine ("ldx #$00"); + if (flags & CF_CONST) { + AddCodeLine ("clc"); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("sta (sp),y"); + } else { + AddCodeLine ("clc"); + AddCodeLine ("adc (sp),y"); + AddCodeLine ("sta (sp),y"); + } if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* Invalidate X */ + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } break; } @@ -1844,10 +1741,10 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val) g_getimmed (flags, val, 0); } if (offs == 0) { - AddCodeLine ("\tjsr\taddeq0sp"); + AddCodeLine ("jsr addeq0sp"); } else { ldyconst (offs); - AddCodeLine ("\tjsr\taddeqysp"); + AddCodeLine ("jsr addeqysp"); } break; @@ -1856,10 +1753,10 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val) g_getimmed (flags, val, 0); } if (offs == 0) { - AddCodeLine ("\tjsr\tladdeq0sp"); + AddCodeLine ("jsr laddeq0sp"); } else { ldyconst (offs); - AddCodeLine ("\tjsr\tladdeqysp"); + AddCodeLine ("jsr laddeqysp"); } break; @@ -1883,47 +1780,39 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - if (offs == 0) { - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(ptr1,x)"); - AddCodeLine ("\tsta\t(ptr1,x)"); - } else { - AddCodeLine ("\tldy\t#$%02X", offs); - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(ptr1),y"); - AddCodeLine ("\tsta\t(ptr1),y"); - } + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$%02X", offs); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("clc"); + AddCodeLine ("adc (ptr1),y"); + AddCodeLine ("sta (ptr1),y"); break; case CF_INT: if (CodeSizeFactor >= 200) { /* Lots of code, use only if size is not important */ - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - AddCodeLine ("\tldy\t#$%02X", offs); - AddCodeLine ("\tlda\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t(ptr1),y"); - AddCodeLine ("\tsta\t(ptr1),y"); - AddCodeLine ("\tpha"); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tadc\t(ptr1),y"); - AddCodeLine ("\tsta\t(ptr1),y"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$%02X", offs); + AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); + AddCodeLine ("clc"); + AddCodeLine ("adc (ptr1),y"); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("pha"); + AddCodeLine ("iny"); + AddCodeLine ("lda #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("adc (ptr1),y"); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("tax"); + AddCodeLine ("pla"); break; } /* FALL THROUGH */ case CF_LONG: - AddCodeLine ("\tjsr\tpushax"); /* Push the address */ + AddCodeLine ("jsr pushax"); /* Push the address */ push (flags); /* Correct the internal sp */ g_getind (flags, offs); /* Fetch the value */ g_inc (flags, val); /* Increment value in primary */ @@ -1949,77 +1838,78 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs, case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tldx\t#$00"); + AddCodeLine ("ldx #$00"); if (flags & CF_CONST) { if (val == 1) { - AddCodeLine ("\tdec\t%s", lbuf); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("dec %s", lbuf); + AddCodeLine ("lda %s", lbuf); } else { - AddCodeLine ("\tsec"); - AddCodeLine ("\tlda\t%s", lbuf); - AddCodeLine ("\tsbc\t#$%02X", (int)(val & 0xFF)); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("sec"); + AddCodeLine ("lda %s", lbuf); + AddCodeLine ("sbc #$%02X", (int)(val & 0xFF)); + AddCodeLine ("sta %s", lbuf); } } else { - AddCodeLine ("\tsec"); - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tlda\t%s", lbuf); - AddCodeLine ("\tsbc\ttmp1"); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("sec"); + AddCodeLine ("sta tmp1"); + AddCodeLine ("lda %s", lbuf); + AddCodeLine ("sbc tmp1"); + AddCodeLine ("sta %s", lbuf); } if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* Invalidate X */ + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } break; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tsec"); + AddCodeLine ("sec"); if (flags & CF_CONST) { - AddCodeLine ("\tlda\t%s", lbuf); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); - AddCodeLine ("\tsta\t%s", lbuf); + AddCodeLine ("lda %s", lbuf); + AddCodeLine ("sbc #$%02X", (unsigned char)val); + AddCodeLine ("sta %s", lbuf); if (val < 0x100) { - label = GetLabel (); - AddCodeLine ("\tbcs\tL%04X", (unsigned)label); - AddCodeLine ("\tdec\t%s+1", lbuf); - g_defloclabel (label); - AddCodeLine ("\tldx\t%s+1", lbuf); + unsigned L = GetLocalLabel (); + AddCodeLine ("bcs %s", LocalLabelName (L)); + AddCodeLine ("dec %s+1", lbuf); + g_defcodelabel (L); + AddCodeLine ("ldx %s+1", lbuf); } else { - AddCodeLine ("\tlda\t%s+1", lbuf); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tsta\t%s+1", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("lda %s+1", lbuf); + AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("sta %s+1", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); } } else { - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tlda\t%s", lbuf); - AddCodeLine ("\tsbc\ttmp1"); - AddCodeLine ("\tsta\t%s", lbuf); - AddCodeLine ("\tstx\ttmp1"); - AddCodeLine ("\tlda\t%s+1", lbuf); - AddCodeLine ("\tsbc\ttmp1"); - AddCodeLine ("\tsta\t%s+1", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t%s", lbuf); + AddCodeLine ("sta tmp1"); + AddCodeLine ("lda %s", lbuf); + AddCodeLine ("sbc tmp1"); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("stx tmp1"); + AddCodeLine ("lda %s+1", lbuf); + AddCodeLine ("sbc tmp1"); + AddCodeLine ("sta %s+1", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); } break; case CF_LONG: if (flags & CF_CONST) { if (val < 0x100) { - AddCodeLine ("\tldy\t#<(%s)", lbuf); - AddCodeLine ("\tsty\tptr1"); - AddCodeLine ("\tldy\t#>(%s+1)", lbuf); + AddCodeLine ("ldy #<(%s)", lbuf); + AddCodeLine ("sty ptr1"); + AddCodeLine ("ldy #>(%s+1)", lbuf); if (val == 1) { - AddCodeLine ("\tjsr\tlsubeq1"); + AddCodeLine ("jsr lsubeq1"); } else { - AddCodeLine ("\tlda\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tlsubeqa"); + AddCodeLine ("lda #$%02X", (unsigned char)val); + AddCodeLine ("jsr lsubeqa"); } } else { g_getstatic (flags, label, offs); @@ -2027,10 +1917,10 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs, g_putstatic (flags, label, offs); } } else { - AddCodeLine ("\tldy\t#<(%s)", lbuf); - AddCodeLine ("\tsty\tptr1"); - AddCodeLine ("\tldy\t#>(%s+1)", lbuf); - AddCodeLine ("\tjsr\tlsubeq"); + AddCodeLine ("ldy #<(%s)", lbuf); + AddCodeLine ("sty ptr1"); + AddCodeLine ("ldy #>(%s+1)", lbuf); + AddCodeLine ("jsr lsubeq"); } break; @@ -2054,21 +1944,22 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { ldyconst (offs); - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tsec"); + AddCodeLine ("ldx #$00"); + AddCodeLine ("sec"); if (flags & CF_CONST) { - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sbc #$%02X", (unsigned char)val); } else { - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tlda\t(sp),y"); - AddCodeLine ("\tsbc\ttmp1"); + AddCodeLine ("sta tmp1"); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sbc tmp1"); } - AddCodeLine ("\tsta\t(sp),y"); + AddCodeLine ("sta (sp),y"); if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdex"); - AddCodeHint ("x:!"); /* Invalidate X */ + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); } break; } @@ -2079,10 +1970,10 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val) g_getimmed (flags, val, 0); } if (offs == 0) { - AddCodeLine ("\tjsr\tsubeq0sp"); + AddCodeLine ("jsr subeq0sp"); } else { ldyconst (offs); - AddCodeLine ("\tjsr\tsubeqysp"); + AddCodeLine ("jsr subeqysp"); } break; @@ -2091,10 +1982,10 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val) g_getimmed (flags, val, 0); } if (offs == 0) { - AddCodeLine ("\tjsr\tlsubeq0sp"); + AddCodeLine ("jsr lsubeq0sp"); } else { ldyconst (offs); - AddCodeLine ("\tjsr\tlsubeqysp"); + AddCodeLine ("jsr lsubeqysp"); } break; @@ -2118,47 +2009,39 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - if (offs == 0) { - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t(ptr1,x)"); - AddCodeLine ("\tsec"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); - AddCodeLine ("\tsta\t(ptr1,x)"); - } else { - AddCodeLine ("\tldy\t#$%02X", offs); - AddCodeLine ("\tldx\t#$00"); - AddCodeLine ("\tlda\t(ptr1),y"); - AddCodeLine ("\tsec"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); - AddCodeLine ("\tsta\t(ptr1),y"); - } + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$%02X", offs); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("sec"); + AddCodeLine ("sbc #$%02X", (unsigned char)val); + AddCodeLine ("sta (ptr1),y"); break; case CF_INT: if (CodeSizeFactor >= 200) { /* Lots of code, use only if size is not important */ - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - AddCodeLine ("\tldy\t#$%02X", offs); - AddCodeLine ("\tlda\t(ptr1),y"); - AddCodeLine ("\tsec"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); - AddCodeLine ("\tsta\t(ptr1),y"); - AddCodeLine ("\tpha"); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t(ptr1),y"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tsta\t(ptr1),y"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$%02X", offs); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("sec"); + AddCodeLine ("sbc #$%02X", (unsigned char)val); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("pha"); + AddCodeLine ("iny"); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("tax"); + AddCodeLine ("pla"); break; } /* FALL THROUGH */ case CF_LONG: - AddCodeLine ("\tjsr\tpushax"); /* Push the address */ + AddCodeLine ("jsr pushax"); /* Push the address */ push (flags); /* Correct the internal sp */ g_getind (flags, offs); /* Fetch the value */ g_dec (flags, val); /* Increment value in primary */ @@ -2181,26 +2064,33 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) void g_addaddr_local (unsigned flags, int offs) /* Add the address of a local variable to ax */ { + unsigned L = 0; + /* Add the offset */ offs -= oursp; if (offs != 0) { /* We cannot address more then 256 bytes of locals anyway */ + L = GetLocalLabel(); CheckLocalOffs (offs); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#$%02X", offs & 0xFF); - AddCodeLine ("\tbcc\t*+4"); /* Do also skip the CLC insn below */ - AddCodeLine ("\tinx"); - AddCodeHint ("x:!"); /* Invalidate X */ + AddCodeLine ("clc"); + AddCodeLine ("adc #$%02X", offs & 0xFF); + /* Do also skip the CLC insn below */ + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); } /* Add the current stackpointer value */ - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\tsp"); - AddCodeLine ("\ttay"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tadc\tsp+1"); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("clc"); + if (L != 0) { + /* Label was used above */ + g_defcodelabel (L); + } + AddCodeLine ("adc sp"); + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("adc sp+1"); + AddCodeLine ("tax"); + AddCodeLine ("tya"); } @@ -2212,13 +2102,13 @@ void g_addaddr_static (unsigned flags, unsigned long label, unsigned offs) char* lbuf = GetLabelName (flags, label, offs); /* Add the address to the current ax value */ - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#<(%s)", lbuf); - AddCodeLine ("\ttay"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tadc\t#>(%s)", lbuf); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("clc"); + AddCodeLine ("adc #<(%s)", lbuf); + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("adc #>(%s)", lbuf); + AddCodeLine ("tax"); + AddCodeLine ("tya"); } @@ -2237,18 +2127,18 @@ void g_save (unsigned flags) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tpha"); + AddCodeLine ("pha"); break; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tsta\tregsave"); - AddCodeLine ("\tstx\tregsave+1"); + AddCodeLine ("sta regsave"); + AddCodeLine ("stx regsave+1"); break; case CF_LONG: - AddCodeLine ("\tjsr\tsaveeax"); + AddCodeLine ("jsr saveeax"); break; default: @@ -2259,25 +2149,25 @@ void g_save (unsigned flags) void g_restore (unsigned flags) -/* Copy hold register to P. */ +/* Copy hold register to primary. */ { /* Check the size and determine operation */ switch (flags & CF_TYPE) { case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tpla"); + AddCodeLine ("pla"); break; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tlda\tregsave"); - AddCodeLine ("\tldx\tregsave+1"); + AddCodeLine ("lda regsave"); + AddCodeLine ("ldx regsave+1"); break; case CF_LONG: - AddCodeLine ("\tjsr\tresteax"); + AddCodeLine ("jsr resteax"); break; default: @@ -2292,20 +2182,24 @@ void g_cmp (unsigned flags, unsigned long val) * will be set. */ { + unsigned L; + /* Check the size and determine operation */ switch (flags & CF_TYPE) { case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - break; + AddCodeLine ("cmp #$%02X", (unsigned char)val); + break; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); + L = GetLocalLabel(); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + g_defcodelabel (L); break; case CF_LONG: @@ -2354,19 +2248,19 @@ static void oper (unsigned flags, unsigned long val, char** subs) /* Constant value given */ if (val == 0 && subs [offs+0]) { /* Special case: constant with value zero */ - AddCodeLine ("\tjsr\t%s", subs [offs+0]); + AddCodeLine ("jsr %s", subs [offs+0]); } else if (val < 0x100 && subs [offs+1]) { /* Special case: constant with high byte zero */ ldaconst (val); /* Load low byte */ - AddCodeLine ("\tjsr\t%s", subs [offs+1]); + AddCodeLine ("jsr %s", subs [offs+1]); } else { /* Others: arbitrary constant value */ g_getimmed (flags, val, 0); /* Load value */ - AddCodeLine ("\tjsr\t%s", subs [offs+2]); + AddCodeLine ("jsr %s", subs [offs+2]); } } else { /* Value not constant (is already in (e)ax) */ - AddCodeLine ("\tjsr\t%s", subs [offs+2]); + AddCodeLine ("jsr %s", subs [offs+2]); } /* The operation will pop it's argument */ @@ -2376,27 +2270,27 @@ static void oper (unsigned flags, unsigned long val, char** subs) void g_test (unsigned flags) -/* Force a test to set cond codes right */ +/* Test the value in the primary and set the condition codes */ { switch (flags & CF_TYPE) { case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\ttax"); + AddCodeLine ("tax"); break; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tstx\ttmp1"); - AddCodeLine ("\tora\ttmp1"); + AddCodeLine ("stx tmp1"); + AddCodeLine ("ora tmp1"); break; case CF_LONG: if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tutsteax"); + AddCodeLine ("jsr utsteax"); } else { - AddCodeLine ("\tjsr\ttsteax"); + AddCodeLine ("jsr tsteax"); } break; @@ -2421,9 +2315,9 @@ void g_push (unsigned flags, unsigned long val) /* Handle as 8 bit value */ if (CodeSizeFactor >= 165 || val > 2) { ldaconst (val); - AddCodeLine ("\tjsr\tpusha"); + AddCodeLine ("jsr pusha"); } else { - AddCodeLine ("\tjsr\tpushc%d", (int) val); + AddCodeLine ("jsr pushc%d", (int) val); } } else { @@ -2431,15 +2325,15 @@ void g_push (unsigned flags, unsigned long val) /* Handle as 16 bit value */ hi = (unsigned char) (val >> 8); if (val <= 7) { - AddCodeLine ("\tjsr\tpush%u", (unsigned) val); + AddCodeLine ("jsr push%u", (unsigned) val); } else if (hi == 0 || hi == 0xFF) { /* Use special function */ ldaconst (val); - AddCodeLine ("\tjsr\t%s", (hi == 0)? "pusha0" : "pushaFF"); + AddCodeLine ("jsr %s", (hi == 0)? "pusha0" : "pushaFF"); } else { /* Long way ... */ g_getimmed (flags, val, 0); - AddCodeLine ("\tjsr\tpushax"); + AddCodeLine ("jsr pushax"); } } @@ -2457,16 +2351,16 @@ void g_push (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { /* Handle as char */ - AddCodeLine ("\tjsr\tpusha"); + AddCodeLine ("jsr pusha"); break; } /* FALL THROUGH */ case CF_INT: - AddCodeLine ("\tjsr\tpushax"); + AddCodeLine ("jsr pushax"); break; case CF_LONG: - AddCodeLine ("\tjsr\tpusheax"); + AddCodeLine ("jsr pusheax"); break; default: @@ -2491,11 +2385,11 @@ void g_swap (unsigned flags) case CF_CHAR: case CF_INT: - AddCodeLine ("\tjsr\tswapstk"); + AddCodeLine ("jsr swapstk"); break; case CF_LONG: - AddCodeLine ("\tjsr\tswapestk"); + AddCodeLine ("jsr swapestk"); break; default: @@ -2513,7 +2407,7 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize) /* Pass the argument count */ ldyconst (ArgSize); } - AddCodeLine ("\tjsr\t_%s", Label); + AddCodeLine ("jsr _%s", Label); oursp += ArgSize; /* callee pops args */ } @@ -2526,7 +2420,7 @@ void g_callind (unsigned Flags, unsigned ArgSize) /* Pass arg count */ ldyconst (ArgSize); } - AddCodeLine ("\tjsr\tcallax"); /* do the call */ + AddCodeLine ("jsr callax"); /* do the call */ oursp += ArgSize; /* callee pops args */ } @@ -2535,7 +2429,7 @@ void g_callind (unsigned Flags, unsigned ArgSize) void g_jump (unsigned Label) /* Jump to specified internal label number */ { - AddCodeLine ("\tjmp\tL%04X", Label); + AddCodeLine ("jmp %s", LocalLabelName (Label)); } @@ -2547,11 +2441,11 @@ void g_switch (unsigned Flags) case CF_CHAR: case CF_INT: - AddCodeLine ("\tjsr\tswitch"); + AddCodeLine ("jsr switch"); break; case CF_LONG: - AddCodeLine ("\tjsr\tlswitch"); + AddCodeLine ("jsr lswitch"); break; default: @@ -2569,14 +2463,14 @@ void g_case (unsigned flags, unsigned label, unsigned long val) case CF_CHAR: case CF_INT: - AddCodeLine ("\t.word\t$%04X, L%04X", + AddCodeLine (".word $%04X, %s", (unsigned)(val & 0xFFFF), - (unsigned)(label & 0xFFFF)); + LocalLabelName (label)); break; case CF_LONG: - AddCodeLine ("\t.dword\t$%08lX", val); - AddCodeLine ("\t.word\tL%04X", label & 0xFFFF); + AddCodeLine (".dword $%08lX", val); + AddCodeLine (".word %s", LocalLabelName (label)); break; default: @@ -2590,11 +2484,7 @@ void g_case (unsigned flags, unsigned label, unsigned long val) void g_truejump (unsigned flags, unsigned label) /* Jump to label if zero flag clear */ { - if (flags & CF_SHORT) { - AddCodeLine ("\tbne\tL%04X", label); - } else { - AddCodeLine ("\tjne\tL%04X", label); - } + AddCodeLine ("jne %s", LocalLabelName (label)); } @@ -2602,11 +2492,7 @@ void g_truejump (unsigned flags, unsigned label) void g_falsejump (unsigned flags, unsigned label) /* Jump to label if zero flag set */ { - if (flags & CF_SHORT) { - AddCodeLine ("\tbeq\tL%04X", label); - } else { - AddCodeLine ("\tjeq\tL%04X", label); - } + AddCodeLine ("jeq %s", LocalLabelName (label)); } @@ -2614,11 +2500,11 @@ void g_falsejump (unsigned flags, unsigned label) static void mod_internal (int k, char* verb1, char* verb2) { if (k <= 8) { - AddCodeLine ("\tjsr\t%ssp%c", verb1, k + '0'); + AddCodeLine ("jsr %ssp%c", verb1, k + '0'); } else { CheckLocalOffs (k); ldyconst (k); - AddCodeLine ("\tjsr\t%ssp", verb2); + AddCodeLine ("jsr %ssp", verb2); } } @@ -2639,7 +2525,7 @@ void g_space (int space) void g_cstackcheck (void) /* Check for a C stack overflow */ { - AddCodeLine ("\tjsr\tcstkchk"); + AddCodeLine ("jsr cstkchk"); } @@ -2647,7 +2533,7 @@ void g_cstackcheck (void) void g_stackcheck (void) /* Check for a stack overflow */ { - AddCodeLine ("\tjsr\tstkchk"); + AddCodeLine ("jsr stkchk"); } @@ -2736,27 +2622,27 @@ void g_mul (unsigned flags, unsigned long val) switch (val) { case 3: - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\ttmp1"); + AddCodeLine ("sta tmp1"); + AddCodeLine ("asl a"); + AddCodeLine ("clc"); + AddCodeLine ("adc tmp1"); return; case 5: - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\ttmp1"); + AddCodeLine ("sta tmp1"); + AddCodeLine ("asl a"); + AddCodeLine ("asl a"); + AddCodeLine ("clc"); + AddCodeLine ("adc tmp1"); return; case 10: - AddCodeLine ("\tsta\ttmp1"); - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\tasl\ta"); - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\ttmp1"); - AddCodeLine ("\tasl\ta"); + AddCodeLine ("sta tmp1"); + AddCodeLine ("asl a"); + AddCodeLine ("asl a"); + AddCodeLine ("clc"); + AddCodeLine ("adc tmp1"); + AddCodeLine ("asl a"); return; } } @@ -2862,7 +2748,7 @@ void g_or (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { if ((val & 0xFF) != 0xFF) { - AddCodeLine ("\tora\t#$%02X", (unsigned char)val); + AddCodeLine ("ora #$%02X", (unsigned char)val); } return; } @@ -2870,14 +2756,14 @@ void g_or (unsigned flags, unsigned long val) case CF_INT: if (val <= 0xFF) { - AddCodeLine ("\tora\t#$%02X", (unsigned char)val); + AddCodeLine ("ora #$%02X", (unsigned char)val); return; } break; case CF_LONG: if (val <= 0xFF) { - AddCodeLine ("\tora\t#$%02X", (unsigned char)val); + AddCodeLine ("ora #$%02X", (unsigned char)val); return; } break; @@ -2920,7 +2806,7 @@ void g_xor (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { if ((val & 0xFF) != 0) { - AddCodeLine ("\teor\t#$%02X", (unsigned char)val); + AddCodeLine ("eor #$%02X", (unsigned char)val); } return; } @@ -2929,15 +2815,15 @@ void g_xor (unsigned flags, unsigned long val) case CF_INT: if (val <= 0xFF) { if (val != 0) { - AddCodeLine ("\teor\t#$%02X", (unsigned char)val); + AddCodeLine ("eor #$%02X", (unsigned char)val); } return; } else if ((val & 0xFF) == 0) { - AddCodeLine ("\tpha"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\teor\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); + AddCodeLine ("pha"); + AddCodeLine ("txa"); + AddCodeLine ("eor #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("pla"); return; } break; @@ -2945,7 +2831,7 @@ void g_xor (unsigned flags, unsigned long val) case CF_LONG: if (val <= 0xFF) { if (val != 0) { - AddCodeLine ("\teor\t#$%02X", (unsigned char)val); + AddCodeLine ("eor #$%02X", (unsigned char)val); } return; } @@ -2987,7 +2873,7 @@ void g_and (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tand\t#$%02X", (unsigned char)val); + AddCodeLine ("and #$%02X", (unsigned char)val); return; } /* FALLTHROUGH */ @@ -2998,23 +2884,23 @@ void g_and (unsigned flags, unsigned long val) if (val == 0) { ldaconst (0); } else if (val != 0xFF) { - AddCodeLine ("\tand\t#$%02X", (unsigned char)val); + AddCodeLine ("and #$%02X", (unsigned char)val); } } else if ((val & 0xFF00) == 0xFF00) { - AddCodeLine ("\tand\t#$%02X", (unsigned char)val); + AddCodeLine ("and #$%02X", (unsigned char)val); } else if ((val & 0x00FF) == 0x0000) { - AddCodeLine ("\ttxa"); - AddCodeLine ("\tand\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\ttax"); + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("tax"); ldaconst (0); } else { - AddCodeLine ("\ttay"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tand\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); if ((val & 0x00FF) != 0x00FF) { - AddCodeLine ("\tand\t#$%02X", (unsigned char)val); + AddCodeLine ("and #$%02X", (unsigned char)val); } } } @@ -3023,16 +2909,16 @@ void g_and (unsigned flags, unsigned long val) case CF_LONG: if (val <= 0xFF) { ldxconst (0); - AddCodeLine ("\tstx\tsreg+1"); - AddCodeLine ("\tstx\tsreg"); + AddCodeLine ("stx sreg+1"); + AddCodeLine ("stx sreg"); if ((val & 0xFF) != 0xFF) { - AddCodeLine ("\tand\t#$%02X", (unsigned char)val); + AddCodeLine ("and #$%02X", (unsigned char)val); } return; } else if (val == 0xFF00) { ldaconst (0); - AddCodeLine ("\tsta\tsreg+1"); - AddCodeLine ("\tsta\tsreg"); + AddCodeLine ("sta sreg+1"); + AddCodeLine ("sta sreg"); return; } break; @@ -3075,13 +2961,13 @@ void g_asr (unsigned flags, unsigned long val) case CF_INT: if (val >= 1 && val <= 3) { if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshrax%ld", val); + AddCodeLine ("jsr shrax%ld", val); } else { - AddCodeLine ("\tjsr\tasrax%ld", val); + AddCodeLine ("jsr asrax%ld", val); } return; } else if (val == 8 && (flags & CF_UNSIGNED)) { - AddCodeLine ("\ttxa"); + AddCodeLine ("txa"); ldxconst (0); return; } @@ -3090,30 +2976,31 @@ void g_asr (unsigned flags, unsigned long val) case CF_LONG: if (val >= 1 && val <= 3) { if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshreax%ld", val); + AddCodeLine ("jsr shreax%ld", val); } else { - AddCodeLine ("\tjsr\tasreax%ld", val); + AddCodeLine ("jsr asreax%ld", val); } return; } else if (val == 8 && (flags & CF_UNSIGNED)) { - AddCodeLine ("\ttxa"); - AddCodeLine ("\tldx\tsreg"); - AddCodeLine ("\tldy\tsreg+1"); - AddCodeLine ("\tsty\tsreg"); - AddCodeLine ("\tldy\t#$00"); - AddCodeLine ("\tsty\tsreg+1"); + AddCodeLine ("txa"); + AddCodeLine ("ldx sreg"); + AddCodeLine ("ldy sreg+1"); + AddCodeLine ("sty sreg"); + AddCodeLine ("ldy #$00"); + AddCodeLine ("sty sreg+1"); return; } else if (val == 16) { - AddCodeLine ("\tldy\t#$00"); - AddCodeLine ("\tldx\tsreg+1"); + AddCodeLine ("ldy #$00"); + AddCodeLine ("ldx sreg+1"); if ((flags & CF_UNSIGNED) == 0) { - AddCodeLine ("\tbpl\t*+3"); - AddCodeLine ("\tdey"); - AddCodeHint ("y:!"); + unsigned L = GetLocalLabel(); + AddCodeLine ("bpl %s", LocalLabelName (L)); + AddCodeLine ("dey"); + g_defcodelabel (L); } - AddCodeLine ("\tlda\tsreg"); - AddCodeLine ("\tsty\tsreg+1"); - AddCodeLine ("\tsty\tsreg"); + AddCodeLine ("lda sreg"); + AddCodeLine ("sty sreg+1"); + AddCodeLine ("sty sreg"); return; } break; @@ -3157,14 +3044,14 @@ void g_asl (unsigned flags, unsigned long val) case CF_INT: if (val >= 1 && val <= 3) { if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshlax%ld", val); + AddCodeLine ("jsr shlax%ld", val); } else { - AddCodeLine ("\tjsr\taslax%ld", val); + AddCodeLine ("jsr aslax%ld", val); } return; } else if (val == 8) { - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t#$00"); + AddCodeLine ("tax"); + AddCodeLine ("lda #$00"); return; } break; @@ -3172,23 +3059,23 @@ void g_asl (unsigned flags, unsigned long val) case CF_LONG: if (val >= 1 && val <= 3) { if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tshleax%ld", val); + AddCodeLine ("jsr shleax%ld", val); } else { - AddCodeLine ("\tjsr\tasleax%ld", val); + AddCodeLine ("jsr asleax%ld", val); } return; } else if (val == 8) { - AddCodeLine ("\tldy\tsreg"); - AddCodeLine ("\tsty\tsreg+1"); - AddCodeLine ("\tstx\tsreg"); - AddCodeLine ("\ttax"); - AddCodeLine ("\tlda\t#$00"); + AddCodeLine ("ldy sreg"); + AddCodeLine ("sty sreg+1"); + AddCodeLine ("stx sreg"); + AddCodeLine ("tax"); + AddCodeLine ("lda #$00"); return; } else if (val == 16) { - AddCodeLine ("\tstx\tsreg+1"); - AddCodeLine ("\tsta\tsreg"); - AddCodeLine ("\tlda\t#$00"); - AddCodeLine ("\ttax"); + AddCodeLine ("stx sreg+1"); + AddCodeLine ("sta sreg"); + AddCodeLine ("lda #$00"); + AddCodeLine ("tax"); return; } break; @@ -3217,11 +3104,11 @@ void g_neg (unsigned flags) case CF_CHAR: case CF_INT: - AddCodeLine ("\tjsr\tnegax"); + AddCodeLine ("jsr negax"); break; case CF_LONG: - AddCodeLine ("\tjsr\tnegeax"); + AddCodeLine ("jsr negeax"); break; default: @@ -3237,15 +3124,15 @@ void g_bneg (unsigned flags) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\tjsr\tbnega"); + AddCodeLine ("jsr bnega"); break; case CF_INT: - AddCodeLine ("\tjsr\tbnegax"); + AddCodeLine ("jsr bnegax"); break; case CF_LONG: - AddCodeLine ("\tjsr\tbnegeax"); + AddCodeLine ("jsr bnegeax"); break; default: @@ -3262,11 +3149,11 @@ void g_com (unsigned flags) case CF_CHAR: case CF_INT: - AddCodeLine ("\tjsr\tcomplax"); + AddCodeLine ("jsr complax"); break; case CF_LONG: - AddCodeLine ("\tjsr\tcompleax"); + AddCodeLine ("jsr compleax"); break; default: @@ -3292,11 +3179,11 @@ void g_inc (unsigned flags, unsigned long val) if (flags & CF_FORCECHAR) { if (CPU == CPU_65C02 && val <= 2) { while (val--) { - AddCodeLine ("\tina"); + AddCodeLine ("ina"); } } else { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#$%02X", (unsigned char)val); + AddCodeLine ("clc"); + AddCodeLine ("adc #$%02X", (unsigned char)val); } break; } @@ -3304,18 +3191,18 @@ void g_inc (unsigned flags, unsigned long val) case CF_INT: if (CPU == CPU_65C02 && val == 1) { - AddCodeLine ("\tina"); - AddCodeLine ("\tbne\t*+3"); - AddCodeLine ("\tinx"); - /* Tell the optimizer that the X register may be invalid */ - AddCodeHint ("x:!"); + unsigned L = GetLocalLabel(); + AddCodeLine ("ina"); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("inx"); + g_defcodelabel (L); } else if (CodeSizeFactor < 200) { /* Use jsr calls */ if (val <= 8) { - AddCodeLine ("\tjsr\tincax%lu", val); + AddCodeLine ("jsr incax%lu", val); } else if (val <= 255) { ldyconst (val); - AddCodeLine ("\tjsr\tincaxy"); + AddCodeLine ("jsr incaxy"); } else { g_add (flags | CF_CONST, val); } @@ -3323,31 +3210,29 @@ void g_inc (unsigned flags, unsigned long val) /* Inline the code */ if (val < 0x300) { if ((val & 0xFF) != 0) { - AddCodeLine ("\tclc"); - AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); - AddCodeLine ("\tbcc\t*+3"); - AddCodeLine ("\tinx"); - /* Tell the optimizer that the X register may be invalid */ - AddCodeHint ("x:!"); + unsigned L = GetLocalLabel(); + AddCodeLine ("clc"); + AddCodeLine ("adc #$%02X", (unsigned char) val); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + g_defcodelabel (L); } if (val >= 0x100) { - AddCodeLine ("\tinx"); + AddCodeLine ("inx"); } if (val >= 0x200) { - AddCodeLine ("\tinx"); + AddCodeLine ("inx"); } } else { - AddCodeLine ("\tclc"); + AddCodeLine ("clc"); if ((val & 0xFF) != 0) { - AddCodeLine ("\tadc\t#$%02X", (unsigned char) val); - /* Tell the optimizer that the X register may be invalid */ - AddCodeHint ("x:!"); + AddCodeLine ("adc #$%02X", (unsigned char) val); } - AddCodeLine ("\tpha"); - AddCodeLine ("\ttxa"); - AddCodeLine ("\tadc\t#$%02X", (unsigned char) (val >> 8)); - AddCodeLine ("\ttax"); - AddCodeLine ("\tpla"); + AddCodeLine ("pha"); + AddCodeLine ("txa"); + AddCodeLine ("adc #$%02X", (unsigned char) (val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("pla"); } } break; @@ -3355,7 +3240,7 @@ void g_inc (unsigned flags, unsigned long val) case CF_LONG: if (val <= 255) { ldyconst (val); - AddCodeLine ("\tjsr\tinceaxy"); + AddCodeLine ("jsr inceaxy"); } else { g_add (flags | CF_CONST, val); } @@ -3385,31 +3270,62 @@ void g_dec (unsigned flags, unsigned long val) if (flags & CF_FORCECHAR) { if (CPU == CPU_65C02 && val <= 2) { while (val--) { - AddCodeLine ("\tdea"); + AddCodeLine ("dea"); } } else { - AddCodeLine ("\tsec"); - AddCodeLine ("\tsbc\t#$%02X", (unsigned char)val); + AddCodeLine ("sec"); + AddCodeLine ("sbc #$%02X", (unsigned char)val); } break; } /* FALLTHROUGH */ case CF_INT: - if (val <= 2) { - AddCodeLine ("\tjsr\tdecax%d", (int) val); - } else if (val <= 255) { - ldyconst (val); - AddCodeLine ("\tjsr\tdecaxy"); + if (CodeSizeFactor < 200) { + /* Use subroutines */ + if (val <= 8) { + AddCodeLine ("jsr decax%d", (int) val); + } else if (val <= 255) { + ldyconst (val); + AddCodeLine ("jsr decaxy"); + } else { + g_sub (flags | CF_CONST, val); + } } else { - g_sub (flags | CF_CONST, val); - } + /* Inline the code */ + if (val < 0x300) { + if ((val & 0xFF) != 0) { + unsigned L = GetLocalLabel(); + AddCodeLine ("sec"); + AddCodeLine ("sbc #$%02X", (unsigned char) val); + AddCodeLine ("bcs %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); + } + if (val >= 0x100) { + AddCodeLine ("dex"); + } + if (val >= 0x200) { + AddCodeLine ("dex"); + } + } else { + AddCodeLine ("sec"); + if ((val & 0xFF) != 0) { + AddCodeLine ("sbc #$%02X", (unsigned char) val); + } + AddCodeLine ("pha"); + AddCodeLine ("txa"); + AddCodeLine ("sbc #$%02X", (unsigned char) (val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("pla"); + } + } break; case CF_LONG: if (val <= 255) { ldyconst (val); - AddCodeLine ("\tjsr\tdeceaxy"); + AddCodeLine ("jsr deceaxy"); } else { g_sub (flags | CF_CONST, val); } @@ -3437,10 +3353,12 @@ void g_eq (unsigned flags, unsigned long val) static char* ops [12] = { "toseq00", "toseqa0", "toseqax", "toseq00", "toseqa0", "toseqax", - 0, 0, "toseqeax", - 0, 0, "toseqeax", + 0, 0, "toseqeax", + 0, 0, "toseqeax", }; + unsigned L; + /* If the right hand side is const, the lhs is not on stack but still * in the primary register. */ @@ -3450,17 +3368,19 @@ void g_eq (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tbooleq"); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + AddCodeLine ("jsr booleq"); return; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tbooleq"); + L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr booleq"); return; case CF_LONG: @@ -3493,6 +3413,7 @@ void g_ne (unsigned flags, unsigned long val) 0, 0, "tosneeax", }; + unsigned L; /* If the right hand side is const, the lhs is not on stack but still * in the primary register. @@ -3503,17 +3424,19 @@ void g_ne (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tboolne"); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + AddCodeLine ("jsr boolne"); return; } /* FALLTHROUGH */ case CF_INT: - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tboolne"); + L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr boolne"); return; case CF_LONG: @@ -3540,10 +3463,10 @@ void g_lt (unsigned flags, unsigned long val) /* Test for less than */ { static char* ops [12] = { - "toslt00", "toslta0", "tosltax", - "tosult00", "tosulta0", "tosultax", - 0, 0, "toslteax", - 0, 0, "tosulteax", + "toslt00", "toslta0", "tosltax", + "tosult00", "tosulta0", "tosultax", + 0, 0, "toslteax", + 0, 0, "tosulteax", }; /* If the right hand side is const, the lhs is not on stack but still @@ -3560,37 +3483,47 @@ void g_lt (unsigned flags, unsigned long val) switch (flags & CF_TYPE) { case CF_CHAR: - if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tboolult"); - } else { - AddCodeLine ("\tjsr\tboollt"); - } - return; - } - /* FALLTHROUGH */ + if (flags & CF_FORCECHAR) { + AddCodeLine ("cmp #$%02X", (unsigned char)val); + if (flags & CF_UNSIGNED) { + AddCodeLine ("jsr boolult"); + } else { + AddCodeLine ("jsr boollt"); + } + return; + } + /* FALLTHROUGH */ case CF_INT: + if ((flags & CF_UNSIGNED) == 0 && val == 0) { + /* If we have a signed compare against zero, we only need to + * test the high byte. + */ + AddCodeLine ("txa"); + AddCodeLine ("jsr boollt"); + return; + } + /* Direct code only for unsigned data types */ + if (flags & CF_UNSIGNED) { + unsigned L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr boolult"); + return; + } + break; + + case CF_LONG: if ((flags & CF_UNSIGNED) == 0 && val == 0) { /* If we have a signed compare against zero, we only need to * test the high byte. */ - AddCodeLine ("\ttxa"); - AddCodeLine ("\tjsr\tboollt"); + AddCodeLine ("lda sreg+1"); + AddCodeLine ("jsr boollt"); return; } - /* Direct code only for unsigned data types */ - if (flags & CF_UNSIGNED) { - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tboolult"); - return; - } - break; - - case CF_LONG: break; default: @@ -3631,11 +3564,11 @@ void g_le (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); + AddCodeLine ("cmp #$%02X", (unsigned char)val); if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tboolule"); + AddCodeLine ("jsr boolule"); } else { - AddCodeLine ("\tjsr\tboolle"); + AddCodeLine ("jsr boolle"); } return; } @@ -3643,10 +3576,12 @@ void g_le (unsigned flags, unsigned long val) case CF_INT: if (flags & CF_UNSIGNED) { - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tboolule"); + unsigned L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr boolule"); return; } break; @@ -3692,19 +3627,19 @@ void g_gt (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); + AddCodeLine ("cmp #$%02X", (unsigned char)val); if (flags & CF_UNSIGNED) { /* If we have a compare > 0, we will replace it by * != 0 here, since both are identical but the latter * is easier to optimize. */ if (val & 0xFF) { - AddCodeLine ("\tjsr\tboolugt"); + AddCodeLine ("jsr boolugt"); } else { - AddCodeLine ("\tjsr\tboolne"); + AddCodeLine ("jsr boolne"); } } else { - AddCodeLine ("\tjsr\tboolgt"); + AddCodeLine ("jsr boolgt"); } return; } @@ -3714,27 +3649,29 @@ void g_gt (unsigned flags, unsigned long val) if (flags & CF_UNSIGNED) { /* If we have a compare > 0, we will replace it by * != 0 here, since both are identical but the latter - * is easier to optimize. - */ - if ((val & 0xFFFF) == 0) { - AddCodeLine ("\tstx\ttmp1"); - AddCodeLine ("\tora\ttmp1"); - AddCodeLine ("\tjsr\tboolne"); - } else { - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tboolugt"); - } - return; + * is easier to optimize. + */ + if ((val & 0xFFFF) == 0) { + AddCodeLine ("stx tmp1"); + AddCodeLine ("ora tmp1"); + AddCodeLine ("jsr boolne"); + } else { + unsigned L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr boolugt"); + } + return; } - break; + break; case CF_LONG: - break; + break; default: - typeerror (flags); + typeerror (flags); } /* If we go here, we didn't emit code. Push the lhs on stack and fall @@ -3776,31 +3713,50 @@ void g_ge (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); + AddCodeLine ("cmp #$%02X", (unsigned char)val); if (flags & CF_UNSIGNED) { - AddCodeLine ("\tjsr\tbooluge"); + AddCodeLine ("jsr booluge"); } else { - AddCodeLine ("\tjsr\tboolge"); + AddCodeLine ("jsr boolge"); } return; } /* FALLTHROUGH */ case CF_INT: - if (flags & CF_UNSIGNED) { - AddCodeLine ("\tcpx\t#$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("\tbne\t*+4"); - AddCodeLine ("\tcmp\t#$%02X", (unsigned char)val); - AddCodeLine ("\tjsr\tbooluge"); + if ((flags & CF_UNSIGNED) == 0 && val == 0) { + /* If we have a signed compare against zero, we only need to + * test the high byte. + */ + AddCodeLine ("txa"); + AddCodeLine ("jsr boolge"); return; } + /* Direct code only for unsigned data types */ + if (flags & CF_UNSIGNED) { + unsigned L = GetLocalLabel(); + AddCodeLine ("cpx #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("cmp #$%02X", (unsigned char)val); + g_defcodelabel (L); + AddCodeLine ("jsr booluge"); + return; + } break; case CF_LONG: - break; + if ((flags & CF_UNSIGNED) == 0 && val == 0) { + /* If we have a signed compare against zero, we only need to + * test the high byte. + */ + AddCodeLine ("lda sreg+1"); + AddCodeLine ("jsr boolge"); + return; + } + break; default: - typeerror (flags); + typeerror (flags); } /* If we go here, we didn't emit code. Push the lhs on stack and fall @@ -3825,7 +3781,7 @@ void g_ge (unsigned flags, unsigned long val) void g_res (unsigned n) /* Reserve static storage, n bytes */ { - AddCodeLine ("\t.res\t%u,$00", n); + AddDataLine ("\t.res\t%u,$00", n); } @@ -3839,15 +3795,15 @@ void g_defdata (unsigned flags, unsigned long val, unsigned offs) switch (flags & CF_TYPE) { case CF_CHAR: - AddCodeLine ("\t.byte\t$%02lX", val & 0xFF); + AddDataLine ("\t.byte\t$%02lX", val & 0xFF); break; case CF_INT: - AddCodeLine ("\t.word\t$%04lX", val & 0xFFFF); + AddDataLine ("\t.word\t$%04lX", val & 0xFFFF); break; case CF_LONG: - AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF); + AddDataLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF); break; default: @@ -3862,7 +3818,7 @@ void g_defdata (unsigned flags, unsigned long val, unsigned offs) const char* Label = GetLabelName (flags, val, offs); /* Labels are always 16 bit */ - AddCodeLine ("\t.word\t%s", Label); + AddDataLine ("\t.word\t%s", Label); } } @@ -3899,7 +3855,7 @@ void g_defbytes (const void* Bytes, unsigned Count) } while (Chunk); /* Output the line */ - AddCodeLine (Buf); + AddDataLine (Buf); } } @@ -3908,7 +3864,27 @@ void g_defbytes (const void* Bytes, unsigned Count) void g_zerobytes (unsigned n) /* Output n bytes of data initialized with zero */ { - AddCodeLine ("\t.res\t%u,$00", n); + AddDataLine ("\t.res\t%u,$00", n); +} + + + +/*****************************************************************************/ +/* User supplied assembler code */ +/*****************************************************************************/ + + + +void g_asmcode (const char* Line, int Len) +/* Output one line of assembler code. If Len is greater than zero, it is used + * as the maximum number of characters to use from Line. + */ +{ + if (Len >= 0) { + AddCodeLine ("%.*s", Len, Line); + } else { + AddCodeLine ("%s", Line); + } } @@ -3923,7 +3899,7 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs) /* Inline the strlen() function */ { /* We need a label in both cases */ - unsigned label = GetLabel (); + unsigned label = GetLocalLabel (); /* Two different encodings */ if (flags & CF_CONST) { @@ -3932,31 +3908,31 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs) char* lbuf = GetLabelName (flags, val, offs); /* Generate the strlen code */ - AddCodeLine ("\tldy\t#$FF"); - g_defloclabel (label); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t%s,y", lbuf); - AddCodeLine ("\tbne\tL%04X", label); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("ldy #$FF"); + g_defcodelabel (label); + AddCodeLine ("iny"); + AddCodeLine ("lda %s,y", lbuf); + AddCodeLine ("bne %s", LocalLabelName (label)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); } else { /* Address not constant but in primary */ if (CodeSizeFactor < 400) { /* This is too much code, so call strlen instead of inlining */ - AddCodeLine ("\tjsr\t_strlen"); + AddCodeLine ("jsr _strlen"); } else { /* Inline the function */ - AddCodeLine ("\tsta\tptr1"); - AddCodeLine ("\tstx\tptr1+1"); - AddCodeLine ("\tldy\t#$FF"); - g_defloclabel (label); - AddCodeLine ("\tiny"); - AddCodeLine ("\tlda\t(ptr1),y"); - AddCodeLine ("\tbne\tL%04X", label); - AddCodeLine ("\ttax"); - AddCodeLine ("\ttya"); + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$FF"); + g_defcodelabel (label); + AddCodeLine ("iny"); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("bne %s", LocalLabelName (label)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); } } }