I'm writing a program in C with a custom makefile and CE toolchain and I have encountered many errors of which I have struggled to but have overcome on my own except for this one where for some reason my program shows up as basic and after inspecting the hex of my program's .8xp file and messaging with ChatGPT to ask why my program won't run I've come to the conclusion that it is missing the "Asm84CEPrgm" signature, however I have been unable to fix this as I've referenced the CE toolchain provided makefile while writing my own but for some reason I can't get my program to run without an immediate error. So what I would like to know is what I could possibly have done wrong in writing my makefile or possibly my initial start.asm (this was used to fix an earlier error). I will provide these files for the purpose of fixing this problem and for future people who have this problem to reference.

Makefile:

Code:
#  == ---------------------------------------------------- ==
#      Cunix
#      [PROJECT] START DATE: 1/6/2025
#      Copyright (c) Samm 2025, All Rights Reserved.
#      Samm
#  == ---------------------------------------------------- ==

NAME  := CUNIX

PLATFORM ?= ti/-84p/ce/py
DEBUG ?= 0
ifneq ($(filter x86 x86/-64,$(PLATFORM)),) # x86

else ifneq ($(filter ti/-84p/ce ti/-84p/ce/py,$(PLATFORM)),) # Ti-84+ CE
CC    := ez80-clang
BCC   := convbin
AS    := fasmg
LINK  := ez80-link
IMGCC := convimg
ALLOC ?= STANDARD
BSSHEAP_LOW ?= D052C6
BSSHEAP_HIGH ?= D13FD8
STACK_HIGH ?= D1A87E
INIT_LOC ?= D1A87F
endif

empty :=
comma :=,
space :=$(empty) $(empty)

SRC := ./src
RES := $(SRC)/res
BUILD_DIR := ./build
OBJ_DIR := $(BUILD_DIR)/objs
BIN_DIR := $(BUILD_DIR)/bin
ifneq ($(filter ti/-84p/ce ti/-84p/ce/py,$(PLATFORM)),) # Ti-84+ CE
TOOLCHAIN := $(shell cedev-config --prefix)
SYSTEM_INC := $(TOOLCHAIN)/include
SYSTEM_LIBDIR := $(TOOLCHAIN)/lib
SYSTEM_LIB := $(filter-out %libload.lib,$(wildcard $(SYSTEM_LIBDIR)/libload/*.lib))
LIBS := $(patsubst %,"%"$(comma)$(space),$(strip $(SYSTEM_LIB)))
endif

ARG_QUOTE = '$(subst ','\'',$1)'

CFLAGS := -nostdinc -I$(SRC) -I$(SYSTEM_INC) -isystem -integrated-as -Wall -Wextra -Oz -std=c11 -target ez80
BINFLAGS := -k 8xp -r -n $(NAME)
# -r -k 8xp-compressed -e zx7 -n $(NAME)
# -r -k 8xp -n $(NAME)

PLATFORM_DIRS := $(SRC)/platforms $(dir $(SRC)/platforms/$(PLATFORM))

C_SOURCES     := $(filter-out $(SRC)/apps/%,$(shell find $(SRC) -type f -name '*.c' ! -path "$(SRC)/platforms/*"))
C_SOURCES     += $(foreach DIR,$(PLATFORM_DIRS),$(wildcard $(DIR)*.c))
APP_C_SOURCES := $(shell find $(SRC)/apps -type f -name '*.c')
# ASM_SOURCES   := $(shell find $(SRC) -type f -name '*.asm' ! -path "$(SRC)/platforms/* ! -path $(SRC)/apps/*")
ASM_SOURCES   := $(foreach DIR,$(PLATFORM_DIRS),$(wildcard $(DIR)*.asm))
ICON := $(RES)/icon.png

OBJ := $(patsubst $(SRC)/%.c,$(OBJ_DIR)/%.c.bc,$(C_SOURCES))
LDBCLTO = $(OBJ_DIR)/lto.bc
LDLTO = $(OBJ_DIR)/lto.src
ICON_OBJ := $(OBJ_DIR)/icon.src

ifneq ($(filter ti/-84p/ce ti/-84p/ce/py,$(PLATFORM)),) # Ti-84+ CE
OUTPUT := $(BIN_DIR)/$(NAME).8xp
OUTPUT_OBJ := $(OBJ_DIR)/$(NAME).bin

# $(TOOLCHAIN)/lib/crt/crt0.src
$(OUTPUT): $(OUTPUT_OBJ)
   @mkdir -p $(BIN_DIR)
   $(BCC) -i $^ -o $@ $(BINFLAGS)

LDFLAGS := -v 0 \
   $(call ARG_QUOTE,$(TOOLCHAIN)/meta/ld.alm) \
   -i $(call ARG_QUOTE,DEBUG := $(DEBUG)) \
   -i $(call ARG_QUOTE,HAS_PRINTF := 0) \
   -i $(call ARG_QUOTE,HAS_LIBC := 1) \
   -i $(call ARG_QUOTE,HAS_LIBCXX := 0) \
   -i $(call ARG_QUOTE,PREFER_OS_CRT := 0) \
   -i $(call ARG_QUOTE,PREFER_OS_LIBC := 0) \
   -i $(call ARG_QUOTE,ALLOCATOR_$(ALLOC) := 1) \
   -i $(call ARG_QUOTE,include "$(TOOLCHAIN)/meta/linker_script") \
   -i $(call ARG_QUOTE,range .bss $$$(BSSHEAP_LOW) : $$$(BSSHEAP_HIGH)) \
   -i $(call ARG_QUOTE,provide __stack = $$$(STACK_HIGH)) \
   -i $(call ARG_QUOTE,locate .header at $$$(INIT_LOC)) \
   -i $(call ARG_QUOTE,source $(patsubst %,"%"$(comma) ,$(LDLTO) $(ASM_SOURCES) $(TOOLCHAIN)/lib/crt/crt0.src)) \
   -i $(call ARG_QUOTE,library $(LIBS))
# -i $(call ARG_QUOTE,source $(ICON_OBJ)$(comma) $(patsubst %,"%"$(comma) ,$(OBJ) $(ASM_SOURCES)))

$(OUTPUT_OBJ): $(LDLTO) $(ICON_OBJ)
   @echo Linking objects...
   $(AS) $(LDFLAGS) $@

$(LDLTO): $(LDBCLTO)
   @$(CC) -S $(EZLTOFLAGS) $(call ARG_QUOTE,$<) -o $(call ARG_QUOTE,$@)

$(LDBCLTO): $(OBJ)
   @$(LINK) $(foreach d,$^,$(call ARG_QUOTE,$d)) -o $(call ARG_QUOTE,$@)

$(OBJ_DIR)/%.c.bc: $(SRC)/%.c
   @mkdir -p $(dir $@)
   @$(CC) -MD -c -emit-llvm $(CFLAGS) $(call ARG_QUOTE,$<) -o $(call ARG_QUOTE,$@)

$(ICON_OBJ): $(ICON)
   @mkdir -p $(dir $@)
   $(IMGCC) --icon '$(ICON)' --icon-output '$(ICON_OBJ)' --icon-format asm

test: clean all
   cemu-autotester ./tests/
endif

all: $(OUTPUT)

clean:
   rm -rf $(BUILD_DIR)

print-vars:
   @echo "C_SOURCES: $(C_SOURCES)"
   @echo "OUTPUT: $(OUTPUT)"
   @echo "LIBS: $(LIBS)"


src/platforms/ti/-84p/ce/start.asm:

Code:
;  == ---------------------------------------------------- ==
;      Cunix
;      [PROJECT] START DATE: 1/6/2025
;      Copyright (c) Samm 2025, All Rights Reserved.
;      Samm
;  == ---------------------------------------------------- ==
    assume adl=1

    section .text
    public __start
    extern _main

__start:
    call _main
    ld   hl, 0
    ret



Thank you for your time,
- Samm
The toolchain makefile has the following section:


Code:
# these are the fasmg linker flags
FASMGFLAGS = \
   $(FASMG_V) \
   $(call QUOTE_ARG,$(call NATIVEPATH,$(CEDEV_TOOLCHAIN)/meta/ld.alm)) \
   -i $(call QUOTE_ARG,DEBUG := $(LDDEBUG)) \
   -i $(call QUOTE_ARG,HAS_PRINTF := $(LDHAS_PRINTF)) \
   -i $(call QUOTE_ARG,HAS_LIBC := $(LDHAS_LIBC)) \
   -i $(call QUOTE_ARG,HAS_LIBCXX := $(LDHAS_LIBCXX)) \
   -i $(call QUOTE_ARG,PREFER_OS_CRT := $(LDPREFER_OS_CRT)) \
   -i $(call QUOTE_ARG,PREFER_OS_LIBC := $(LDPREFER_OS_LIBC)) \
   -i $(call QUOTE_ARG,ALLOCATOR_$(ALLOCATOR) := 1) \
   -i $(call QUOTE_ARG,include $(call FASMG_FILES,$(LINKER_SCRIPT))) \
   -i $(call QUOTE_ARG,range .bss $$$(BSSHEAP_LOW) : $$$(BSSHEAP_HIGH)) \
   -i $(call QUOTE_ARG,provide __stack = $$$(STACK_HIGH)) \
   -i $(call QUOTE_ARG,locate .header at $$$(INIT_LOC)) \
   $(LDMAPFLAG) \
   -i $(call QUOTE_ARG,source $(LDICON)$(call FASMG_FILES,$(LDFILES))) \
   -i $(call QUOTE_ARG,library $(LDLIBS)) \
   $(EXTRA_LDFLAGS)


The line we're looking at is

Code:
   -i $(call QUOTE_ARG,locate .header at $$$(INIT_LOC)) \
. The linker is looking in crt0.src for the .header:

Code:
   section   .header
   db   $EF, $7B
   db   $00      ; C program identifier (nop)


Referring to the ez80 Heaven - Program Structure page I can see:

Code:
.db tExtTok,tAsm84CeCmp

Quote:
This is exactly equivalent to the Asm84CEPrgm token in BASIC; it tells your calculator that it should be executing an assembly program instead of a BASIC program.


So perhaps in start.asm you need the

Code:
.db tExtTok,tAsm84CeCmp
or
Code:
db   $EF, $7B
merthsoft wrote:
The toolchain makefile has the following section:


Code:
# these are the fasmg linker flags
FASMGFLAGS = \
   $(FASMG_V) \
   $(call QUOTE_ARG,$(call NATIVEPATH,$(CEDEV_TOOLCHAIN)/meta/ld.alm)) \
   -i $(call QUOTE_ARG,DEBUG := $(LDDEBUG)) \
   -i $(call QUOTE_ARG,HAS_PRINTF := $(LDHAS_PRINTF)) \
   -i $(call QUOTE_ARG,HAS_LIBC := $(LDHAS_LIBC)) \
   -i $(call QUOTE_ARG,HAS_LIBCXX := $(LDHAS_LIBCXX)) \
   -i $(call QUOTE_ARG,PREFER_OS_CRT := $(LDPREFER_OS_CRT)) \
   -i $(call QUOTE_ARG,PREFER_OS_LIBC := $(LDPREFER_OS_LIBC)) \
   -i $(call QUOTE_ARG,ALLOCATOR_$(ALLOCATOR) := 1) \
   -i $(call QUOTE_ARG,include $(call FASMG_FILES,$(LINKER_SCRIPT))) \
   -i $(call QUOTE_ARG,range .bss $$$(BSSHEAP_LOW) : $$$(BSSHEAP_HIGH)) \
   -i $(call QUOTE_ARG,provide __stack = $$$(STACK_HIGH)) \
   -i $(call QUOTE_ARG,locate .header at $$$(INIT_LOC)) \
   $(LDMAPFLAG) \
   -i $(call QUOTE_ARG,source $(LDICON)$(call FASMG_FILES,$(LDFILES))) \
   -i $(call QUOTE_ARG,library $(LDLIBS)) \
   $(EXTRA_LDFLAGS)


The line we're looking at is

Code:
   -i $(call QUOTE_ARG,locate .header at $$$(INIT_LOC)) \
. The linker is looking in crt0.src for the .header:

Code:
   section   .header
   db   $EF, $7B
   db   $00      ; C program identifier (nop)


Referring to the ez80 Heaven - Program Structure page I can see:

Code:
.db tExtTok,tAsm84CeCmp

Quote:
This is exactly equivalent to the Asm84CEPrgm token in BASIC; it tells your calculator that it should be executing an assembly program instead of a BASIC program.


So perhaps in start.asm you need the

Code:
.db tExtTok,tAsm84CeCmp
or
Code:
db   $EF, $7B


Thank you for your quick response. Sorry but I do have a question, could you clarify if there's specific section I need to put "db $EF, $7B" under, because I can't seem to get it to work when it's in the ".text" section inside the start.asm. Sorry, I'm not very good with assembly.

But again thank you very much,
- Samm
Samm wrote:
Thank you for your quick response. Sorry but I do have a question, could you clarify if there's specific section I need to put "db $EF, $7B" under, because I can't seem to get it to work when it's in the ".text" section inside the start.asm. Sorry, I'm not very good with assembly.

But again thank you very much,
- Samm


Pretty sure it should be in the very start of the file so that it is the first two bytes to be added to the assembled program
You want those two bytes at
Code:
.org userMem-2
StephenM wrote:
Samm wrote:
Thank you for your quick response. Sorry but I do have a question, could you clarify if there's specific section I need to put "db $EF, $7B" under, because I can't seem to get it to work when it's in the ".text" section inside the start.asm. Sorry, I'm not very good with assembly.

But again thank you very much,
- Samm


Pretty sure it should be in the very start of the file so that it is the first two bytes to be added to the assembled program

Hmm... It seems to add it starting at the 4B byte.
Here's the full CUNIX.8xp:

Code:
**TI83F*
�������������������������������������������K
�:CUNIX�����:8�{�{��(�H!���� >2��� 8͘(�!������ܨ������(!�������!�����Ì
�LibLoad�)�GRAPHX� ��������������!���6���<���?���N������!����99�������!����9�͢��!����!���������!��������.��E()��<�w�!���������b�������~��.>�(o���ѷ�b3����!���'b��l��   ��B(������!�������5��   ��B�Z����/����!��������! ��������7�b�� ����b������b��!{����������'��͇���/���������!@���R���̀���b?͈��|�!x�����'��������!����������<�(����b������������b�����No error.�Unknown error.�Press any button to quit.�Need LibLoad�http://tiny.cc/clibs��

and the hex:

Code:

2a2a54493833462a1a0a000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b020d003a020643554e495800000000803a023802ef7bef7b00cd2806021804cd4814022199aad1cd2003023e1532f805d0cd0c05023816cd981f0228e22113000019e5cdc40502e111dca8d1e9cdc40502cd140802cd2808022195aad1cdc00702cdf0070221a2aad1cdc00702c38c0d02c04c69624c6f61640029c0475241504858000cc3000000c3030000c30f0000c31b0000c3210000c3360000c33c0000c33f0000c34e0000d1dde5dd21000000dd3939f9ebe9e1dde5dd21000000dd39e9cda2a9d121000000c921ffffffcd13a9d1cdefa8d121010000e5cdfba8d1e12e011800cb4528291800cd3c1d02dd77ff210e0000e5cdf7a8d1e1b7ed62e5cdffa8d1e1dd7effb72e013e0028016f18d3cdf3a8d1b7ed6233dde1c9cd21a9d1dd27061162aad1016caad109b7ed422802c5d1ebdde1c921fdffffcd13a9d1cd35a9d109b7ed42ca5aaad11800dd2ffdcdefa8d121010000e5cdfba8d1e1210b0000e5cdf7a8d1e137ed62e5cd0ba9d1e1b7ed62e5cd07a9d1e1b7ed62e5e5217baad1e5cd03a9d1e1e1e1dd27fde5cd87a9d1dd2ffdd1e5cd0fa9d1e5d1e121400100b7ed52e5c1afcd800200b7ed621e3fcd880200cd7c020021780000e5c5dd27fde5cd03a9d1e1e1e121010000e5cdffa8d1e11800cd3c1d02b728f91800b7ed62e5cdf7a8d1e1cdf3a8d11800b7ed62ddf9dde1c94e6f206572726f722e00556e6b6e6f776e206572726f722e00507265737320616e7920627574746f6e20746f20717569742e004e656564204c69624c6f616400687474703a2f2f74696e792e63632f636c69627300fc0d
merthsoft wrote:
You want those two bytes at
Code:
.org userMem-2

Thanks, but org gives me an invalid instruction error when compiling.
Referring to the same sources as before, you want this located at
Code:
.org userMem-2
. userMem is
Code:
?userMem                   := 0D1A881h


Look at the line I posted previously:

Code:
   -i $(call QUOTE_ARG,locate .header at $$$(INIT_LOC)) \

It's locating it at

Code:
INIT_LOC
which is defined as
Code:
INIT_LOC ?= D1A87F


Also note you will want an additional 0x00 after those two bytes to signal to shells that this is a C program.


Code:
.org userMem-2
   .db   $EF, $7B
   .db   $00      ; C program identifier (nop)


Quote:
Thanks, but org gives me an invalid instruction error when compiling.

I don't know the right keyword for it, but you'll want to use the right thing to locate it at D1A87F. I would probably do it through the linker instead of in the .asm file, but that's only because that's how the reference does it and I don't actually know a whole lot.
Samm wrote:
merthsoft wrote:
You want those two bytes at
Code:
.org userMem-2

Thanks, but org gives me an invalid instruction error when compiling.


.org is a spasm directive - it won't work for fasmg, especially with the linker setup the toolchain uses. Don't reference eZ80 Heaven; when that was written only spasm existed so it uses entirely spasm syntax. I don't think the issue here is with the org address - if that were the case the header bytes would still be in the correct place but all pointers to labels inside the program would be incorrect.

The linker is already configured to put the .header section at the very start of the program, and to configure the org address correctly. If you're not seeing the header bytes at the start of the program, it's either because you've changed the linker configuration in a way that removes the header section, or crt0.src isn't getting linked.

Could I ask why you're not using the default makefile? Custom makefiles that don't include from the main toolchain makefile aren't really something supported by the toolchain, and there might be a way to do what you want without ditching the toolchain makefile.

Samm wrote:
Hmm... It seems to add it starting at the 4B byte.
.8xp files are container files that include a header before the start of the program. The .bin file that the toolchain produces are the actual contents of the program, and ef7b should be the first two bytes of that.
commandblockguy wrote:
Samm wrote:
merthsoft wrote:
You want those two bytes at
Code:
.org userMem-2

Thanks, but org gives me an invalid instruction error when compiling.


.org is a spasm directive - it won't work for fasmg, especially with the linker setup the toolchain uses. Don't reference eZ80 Heaven; when that was written only spasm existed so it uses entirely spasm syntax. I don't think the issue here is with the org address - if that were the case the header bytes would still be in the correct place but all pointers to labels inside the program would be incorrect.

The linker is already configured to put the .header section at the very start of the program, and to configure the org address correctly. If you're not seeing the header bytes at the start of the program, it's either because you've changed the linker configuration in a way that removes the header section, or crt0.src isn't getting linked.

Could I ask why you're not using the default makefile? Custom makefiles that don't include from the main toolchain makefile aren't really something supported by the toolchain, and there might be a way to do what you want without ditching the toolchain makefile.

Samm wrote:
Hmm... It seems to add it starting at the 4B byte.
.8xp files are container files that include a header before the start of the program. The .bin file that the toolchain produces are the actual contents of the program, and ef7b should be the first two bytes of that.


The only thing I can possibly fathem being the problem at this point then is crt0.src some how not being linked as I haven't changed any of the linker scripts and I'm just using the default CE toolchain provided ones.
Why are you doing insane things and not just reading the documenation and refering to the examples. Stop using ChatGPT.

This is really all your makefile should contain: https://github.com/CE-Programming/toolchain/blob/master/examples/hello_world/makefile

Makefile parameters are documented here: https://ce-programming.github.io/toolchain/static/makefile-options.html
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement