__STACKSIZE__: type = weak, value = $0800; # 2k stack
}
MEMORY {
- ZP: file = "", start = $0000, size = $001A;
+ ZP: file = "", start = $0000, size = $001B;
HEADER: file = %O, start = $0000, size = $0001;
MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__;
}
__STACKSIZE__: type = weak, value = $0800; # 2k stack
}
MEMORY {
- ZP: file = "", start = $0000, size = $001A;
+ ZP: file = "", start = $0000, size = $001B;
HEADER: file = %O, start = $0000, size = $0001;
MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__;
}
<title>cc65 Users Guide
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
<url url="mailto:gregdk@users.sf.net" name="Greg King">
-<date>2017-02-27
+<date>2017-03-21
<abstract>
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
As a shortcut, you can put the <tt/volatile/ qualifier in your <tt/asm/
statements. It will disable optimization for the functions in which those
<tt/asm volatile/ statements sit. The effect is the same as though you put
-</#pragma optimize(push, off)/ above those functions, and </#pragma
+<tt/#pragma optimize(push, off)/ above those functions, and <tt/#pragma
optimize(pop)/ below those functions.
The string literal may contain format specifiers from the following list. For
CFLAGS += -MMD -MP -O -I common \
-Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \
-DCA65_INC=$(CA65_INC) -DCC65_INC=$(CC65_INC) -DCL65_TGT=$(CL65_TGT) \
- -DLD65_LIB=$(LD65_LIB) -DLD65_OBJ=$(LD65_OBJ) -DLD65_CFG=$(LD65_CFG)
+ -DLD65_LIB=$(LD65_LIB) -DLD65_OBJ=$(LD65_OBJ) -DLD65_CFG=$(LD65_CFG) \
-DGIT_SHA=$(GIT_SHA)
LDLIBS += -lm
Error ("Variable `%s' has unknown size", Decl.Ident);
}
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
+ } else {
+ /* A global (including static) uninitialized variable
+ ** is only a tentative definition. For example, this is valid:
+ ** int i;
+ ** int i;
+ ** static int j;
+ ** static int j = 42;
+ ** Code for these will be generated in FinishCompile.
+ ** For now, just save the BSS segment name
+ ** (can be set with #pragma bss-name)
+ */
+ const char* bssName = GetSegName (SEG_BSS);
+ if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {
+ Error ("Global variable `%s' has already been defined in `%s' segment",
+ Entry->Name, Entry->V.BssName);
+ }
+ Entry->V.BssName = xstrdup (bssName);
}
-
- /* A global (including static) uninitialized variable
- ** is only a tentative definition. For example, this is valid:
- ** int i;
- ** int i;
- ** static int j;
- ** static int j = 42;
- ** Code for these will be generated in FinishCompile.
- */
}
}
} else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
/* Tentative definition of uninitialized global variable */
g_usebss ();
+ SetSegName (SEG_BSS, Entry->V.BssName);
+ g_segname (SEG_BSS); /* TODO: skip if same as before */
g_defgloblabel (Entry->Name);
g_res (SizeOf (Entry->Type));
/* Mark as defined, so that it will be exported not imported */
E->Type = 0;
E->Attr = 0;
E->AsmName = 0;
+ E->V.BssName = 0;
memcpy (E->Name, Name, Len+1);
/* Return the new entry */
struct LiteralPool* LitPool; /* Literal pool for this function */
} F;
+ /* Segment name for tentantive global definitions */
+ const char* BssName;
} V;
char Name[1]; /* Name, dynamically allocated */
};
unsigned Addr;
unsigned char Val;
Cycles = 6;
- Addr = MemReadByte (Regs.PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr);
SET_ZF ((Val & Regs.AC) == 0);
MemWriteByte (Addr, (unsigned char) (Val | Regs.AC));
unsigned Addr;
unsigned char Val;
Cycles = 6;
- Addr = MemReadByte (Regs.PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr);
SET_ZF ((Val & Regs.AC) == 0);
MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC));
--- /dev/null
+/*
+ !!DESCRIPTION!! conflicting bss-name pragmas
+ !!ORIGIN!! cc65 regression tests
+ !!LICENCE!! Public Domain
+ !!AUTHOR!! Piotr Fusik
+*/
+
+/*
+ see: https://github.com/cc65/cc65/issues/409
+*/
+
+char oam_off;
+#pragma bss-name (push,"ZEROPAGE")
+char oam_off;
+#pragma bss-name (pop)
+
+int main(void)
+{
+ return 0;
+}
.PHONY: all clean
SOURCES := $(wildcard *.c)
-TESTS := $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg))
+TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg))
TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg))
-# FIXME: These tests fail when built with optimizations for the 65c02
-TESTS := $(filter-out $(WORKDIR)/compare7.O%.65c02.prg,$(TESTS))
-TESTS := $(filter-out $(WORKDIR)/compare8.O%.65c02.prg,$(TESTS))
-TESTS := $(filter-out $(WORKDIR)/compare9.O%.65c02.prg,$(TESTS))
-TESTS := $(filter-out $(WORKDIR)/compare10.O%.65c02.prg,$(TESTS))
-TESTS := $(filter-out $(WORKDIR)/or1.O%.65c02.prg,$(TESTS))
-
all: $(TESTS)
$(WORKDIR):
--- /dev/null
+/*
+ !!DESCRIPTION!! bss-name pragma not affecting declarations
+ !!ORIGIN!! cc65 regression tests
+ !!LICENCE!! Public Domain
+ !!AUTHOR!! Piotr Fusik
+*/
+
+/*
+ see: https://github.com/cc65/cc65/issues/409
+*/
+
+#pragma bss-name (push,"ZEROPAGE")
+
+char n; /* only a declaration because followed by definition */
+char n = 1; /* not BSS */
+
+#pragma bss-name (pop)
+
+int main(void)
+{
+ return (unsigned) &n >= 0x100 ? 0 : 1;
+}
--- /dev/null
+/*
+ !!DESCRIPTION!! bss-name pragma
+ !!ORIGIN!! cc65 regression tests
+ !!LICENCE!! Public Domain
+ !!AUTHOR!! Piotr Fusik
+*/
+
+/*
+ see: https://github.com/cc65/cc65/issues/409
+*/
+
+#pragma bss-name (push,"ZEROPAGE")
+
+char zp_var;
+
+#pragma bss-name (pop)
+
+int main(void)
+{
+ return (unsigned) &zp_var < 0x100 ? 0 : 1;
+}