From 328a5e908180882aee62853157ab4b1a735ec11d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 8 Mar 2015 21:40:31 +0000 Subject: [PATCH] libs: Support Z80 variant builds Allow PLATFORM to be set and make it use a different crt0 and syscall.s file. We need this for platforms like ZX128 where we can't use the normal RST calls. For relocatable binaries when we get there the syscall vector is going to need to be discoverable - perhaps passed in a register or on the passed stack ? --- Library/libs/Makefile | 18 +++--- Library/libs/crt0-zx128.s | 90 ++++++++++++++++++++++++++++++ Library/libs/fuzix/Makefile | 2 +- Library/libs/fuzix/syscall-zx128.s | 15 +++++ Library/tools/syscall.c | 2 +- 5 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 Library/libs/crt0-zx128.s create mode 100644 Library/libs/fuzix/syscall-zx128.s diff --git a/Library/libs/Makefile b/Library/libs/Makefile index 2f5d734f..c3356e72 100644 --- a/Library/libs/Makefile +++ b/Library/libs/Makefile @@ -2,13 +2,17 @@ CC = sdcc ASM = sdasz80 AR = sdar LINKER = sdldz80 +# This gets set for 'awkward' devices like ZX128 +#PLATFORM = -zx128 +PLATFORM = +export PLATFORM #CC_OPT = -mz80 -c --opt-code-size --std-c99 --max-allocs-per-node 2000000 -I../include CC_OPT = -mz80 --std-c99 -c --opt-code-size --max-allocs-per-node 20000 -I../include # for stuff that gives sdcc nightmares CC_NOOPT = -mz80 --std-c99 -c --opt-code-size --max-allocs-per-node 1000 -I../include ASM_OPT = -l -o -s LINKER_OPT = -m -i -o -SRC_CRT0 = crt0.s +SRC_CRT0 = crt0$(PLATFORM).s OBJ_CRT0 = $(SRC_CRT0:.s=.rel) SRC_ASM = OBJ_ASM = $(SRC_ASM:.s=.rel) @@ -56,7 +60,7 @@ OBJ_C = $(SRC_C:.c=.rel) OBJ_HARD = $(SRC_HARD:.c=.rel) OBJ_ALL = $(OBJ_ASM) $(OBJ_C) $(OBJ_HARD) -all: syslib.lib crt0.rel +all: syslib$(PLATFORM).lib crt0$(PLATFORM).rel libc.l:%.l:$(OBJ_ALL) ls $(OBJ_ALL) > libc.l @@ -69,12 +73,12 @@ syscall.l: fuzix/syslib.l sdccz80.lib: ../tools/libclean -syslib.lib: syscall.l libc.l sdccz80.lib +syslib$(PLATFORM).lib: syscall.l libc.l sdccz80.lib cat libc.l syscall.l >syslib.l - cp sdccz80.lib syslib.lib - $(AR) rc syslib.lib @syslib.l - $(AR) s syslib.lib - ln -sf syslib.lib c.lib + cp sdccz80.lib syslib$(PLATFORM).lib + $(AR) rc syslib$(PLATFORM).lib @syslib.l + $(AR) s syslib$(PLATFORM).lib + ln -sf syslib$(PLARFORM).lib c$(PLATFORM).lib fuzix/syslib.l: ../tools/syscall diff --git a/Library/libs/crt0-zx128.s b/Library/libs/crt0-zx128.s new file mode 100644 index 00000000..52aa0262 --- /dev/null +++ b/Library/libs/crt0-zx128.s @@ -0,0 +1,90 @@ + .module crt0 + + .area _CODE + .area _HOME + .area _CONST + ; The _GS can be blown away after startup. We don't yet + ; but we should do FIXME + .area _GSINIT + .area _GSFINAL + .area _INITIALIZED + .area _BSEG + .area _DATA + .area _BSS + ; note that the binary builder moves the initialized data + ; from initializer + .area _INITIALIZER + + .globl ___stdio_init_vars + .globl _main + .globl _exit + .globl _environ + .globl ___argv + + .globl s__DATA + .globl l__DATA + .globl s__INITIALIZED + + .area _CODE + +; start at 0x8000 +start: jp start2 + .db 'F' + .db 'Z' + .db 'X' + .db '1' + +; +; Borrowed idea from UMZIX - put the info in known places then +; we can write "size" tools +; +; This is confusing. SDCC doesn't produce a BSS, instead it +; produces an INITIALIZED (which everyone else calls DATA) and a +; DATA which everyone else would think of as BSS. +; +; FIXME: we need to automate the load page setting +; + .db 0x80 ; page to load at + .dw 0 ; chmem ("0 - 'all'") + .dw s__INITIALIZED ; gives us code size info + .dw s__DATA ; gives us data size info + .dw l__DATA ; bss size info + .dw 0 ; spare + +start2: ld hl, #l__DATA - 1 ; work around linker limit + ld b, h + ld c, l + ld hl, #s__DATA + ld de, #s__DATA+1 + ld (hl), #0 + ldir + call gsinit + + ld hl, #4 + add hl, sp + ld (_environ), hl + pop de ; argc + pop hl ; argv + push hl + ld (___argv), hl ; needed for stuff like err() + push de + ld hl, #_exit ; return vector + push hl + jp _main ; go + + .area _GSINIT +; +; FIXME: we want to work this into the C code so it's not +; automatically sucking in any of stdio at all. +; +gsinit: + call ___stdio_init_vars +; +; Any gsinit code from other modules will accumulate between here +; and _GSFINAL to provide constructors and other ghastly C++isms +; + .area _GSFINAL + ret + + .area _DATA +_environ: .dw 0 diff --git a/Library/libs/fuzix/Makefile b/Library/libs/fuzix/Makefile index d5ddf5d9..79568d84 100644 --- a/Library/libs/fuzix/Makefile +++ b/Library/libs/fuzix/Makefile @@ -4,7 +4,7 @@ CROSS_LD=sdldz80 CROSS_AR=sdar ASOPTS= -ASYS=syscall.s +ASYS=syscall$(PLATFORM).s ASRCS = syscall__exit.s ASRCS += syscall_open.s ASRCS += syscall_close.s diff --git a/Library/libs/fuzix/syscall-zx128.s b/Library/libs/fuzix/syscall-zx128.s new file mode 100644 index 00000000..3675d8fa --- /dev/null +++ b/Library/libs/fuzix/syscall-zx128.s @@ -0,0 +1,15 @@ + .globl __syscall + .globl _errno + +__syscall: + ex (sp), hl ; hl is now return addr + ; stack is syscall + ex de, hl ; save return addr in de + call #0xFFF7 ; magic number + ex de, hl ; undo the magic + ex (sp), hl + ex de, hl ; return with HL + ret nc ; ok + ld (_errno), hl ; error path + ld hl, #0xffff + ret diff --git a/Library/tools/syscall.c b/Library/tools/syscall.c index ba00232c..e417ae8b 100644 --- a/Library/tools/syscall.c +++ b/Library/tools/syscall.c @@ -44,7 +44,7 @@ static void write_makefile(void) fprintf(fp, "# Autogenerated by tools/syscall\n"); fprintf(fp, "CROSS_AS=sdasz80\nCROSS_LD=sdldz80\nCROSS_AR=sdar\n"); fprintf(fp, "ASOPTS=\n\n"); - fprintf(fp, "ASYS=syscall.s\n"); + fprintf(fp, "ASYS=syscall$(PLATFORM).s\n"); fprintf(fp, "ASRCS = syscall_%s.s\n", syscall_name[0]); for (i = 1; i < NR_SYSCALL; i++) fprintf(fp, "ASRCS += syscall_%s.s\n", syscall_name[i]); -- 2.34.1