libs: Support Z80 variant builds
authorAlan Cox <alan@linux.intel.com>
Sun, 8 Mar 2015 21:40:31 +0000 (21:40 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 8 Mar 2015 21:40:31 +0000 (21:40 +0000)
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
Library/libs/crt0-zx128.s [new file with mode: 0644]
Library/libs/fuzix/Makefile
Library/libs/fuzix/syscall-zx128.s [new file with mode: 0644]
Library/tools/syscall.c

index 2f5d734..c3356e7 100644 (file)
@@ -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 (file)
index 0000000..52aa026
--- /dev/null
@@ -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
index d5ddf5d..79568d8 100644 (file)
@@ -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 (file)
index 0000000..3675d8f
--- /dev/null
@@ -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
index ba00232..e417ae8 100644 (file)
@@ -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]);