From: cuz Date: Mon, 27 Nov 2000 16:52:52 +0000 (+0000) Subject: Implemented large offsets for g_putind X-Git-Tag: V2.12.0~3053 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5be5b3763bbca73ad0b95f005ffa7224cbc04196;p=cc65 Implemented large offsets for g_putind git-svn-id: svn://svn.cc65.org/cc65/trunk@483 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index b1bcbbd3b..3d1bd3ffd 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1039,48 +1039,81 @@ void g_putlocal (unsigned flags, int offs) -void g_putind (unsigned flags, unsigned offs) +void g_putind (unsigned Flags, unsigned Offs) /* Store the specified object type in the primary register at the address * on the top of the stack */ { - /* We cannot currently handle more than byte sized offsets */ - if (offs > 256 - sizeofarg (flags)) { - Internal ("g_putind: Large offsets not implemented"); + /* We can handle offsets below $100 directly, larger offsets must be added + * to the address. Since a/x is in use, best code is achieved by adding + * just the high byte. Be sure to check if the low byte will overflow while + * while storing. + */ + 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"); + + /* Complete address is on stack, new offset is zero */ + Offs = 0; + + } 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"); + + /* Offset is now just the low byte */ + Offs &= 0x00FF; } /* Check the size and determine operation */ - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: - if (offs) { - ldyconst (offs); + if (Offs) { + ldyconst (Offs); AddCodeLine ("\tjsr\tstaspidx"); } else { - AddCodeLine ("\tjsr\tstaspp"); + AddCodeLine ("\tjsr\tstaspp"); } break; case CF_INT: - if (offs) { - ldyconst (offs); - AddCodeLine ("\tjsr\tstaxspidx"); + if (Offs) { + ldyconst (Offs); + AddCodeLine ("\tjsr\tstaxspidx"); } else { - AddCodeLine ("\tjsr\tstaxspp"); + AddCodeLine ("\tjsr\tstaxspp"); } break; case CF_LONG: - if (offs) { - ldyconst (offs); - AddCodeLine ("\tjsr\tsteaxspidx"); + if (Offs) { + ldyconst (Offs); + AddCodeLine ("\tjsr\tsteaxspidx"); } else { - AddCodeLine ("\tjsr\tsteaxspp"); + AddCodeLine ("\tjsr\tsteaxspp"); } break; default: - typeerror (flags); + typeerror (Flags); }