--- /dev/null
+ .code
+
+; start at 0x100
+start: jp start2
+ .byte 'F'
+ .byte 'Z'
+ .byte 'X'
+ .byte '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
+;
+ .byte 0x01 ; page to load at
+ .word 0 ; chmem ("0 - 'all'")
+ .word __code_size ; gives us code size info
+ .word __data_size ; gives us data size info
+ .word __bss_size ; bss size info
+ .word 0 ; spare
+
+start2:
+ 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
+
+ .data
+
+_environ: .word 0
+___argv: .word 0
--- /dev/null
+ .export __syscall
+
+ .code
+__syscall:
+ ex (sp), hl ; hl is now return addr
+ ; stack is syscall
+ ex de, hl ; save return addr in de
+ rst 0x30
+ 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
+
+ .data
+
+_errno: .word 0
--- /dev/null
+/*
+ * Generate the syscall functions. For Z80 at the moment. Extend to
+ * do the others as well
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "syscall_name.h"
+
+static char namebuf[128];
+
+/*
+ * For Z80 it's kind of simple - load the call number and jump
+ * to the common helper.
+ */
+static void write_Z80_call(int n)
+{
+ FILE *fp;
+ snprintf(namebuf, 128, "Z80/syscall/_%s.s", syscall_name[n]);
+ fp = fopen(namebuf, "w");
+ if (fp == NULL) {
+ perror(namebuf);
+ exit(1);
+ }
+ fprintf(fp, "\t.code\n\n");
+ fprintf(fp, "\t.export _%s\n\n", syscall_name[n]);
+ fprintf(fp, "_%s:\n\tld hl, %d\n", syscall_name[n], n);
+ fprintf(fp, "\tjp __syscall\n");
+ fclose(fp);
+}
+
+static void write_Z80_call_table(void)
+{
+ int i;
+ for (i = 0; i < NR_SYSCALL; i++)
+ write_Z80_call(i);
+}
+
+static void write_Z80_makefile(void)
+{
+ int i;
+ FILE *fp = fopen("Z80/syscall/Makefile", "w");
+ if (fp == NULL) {
+ perror("Makefile");
+ exit(1);
+ }
+ fprintf(fp, "SRCS = syscall.s\n", syscall_name[0]);
+ for (i = 0; i < NR_SYSCALL; i++)
+ fprintf(fp, "SRCS += _%s.s\n", syscall_name[i]);
+ fprintf(fp, "\nsyscall.a: $(SRCS)\n");
+ fprintf(fp, "\t$(CROSS_AR) rc syslib.lib $(OBJS)\n\n");
+ fprintf(fp, "$(OBJS): %%.o: %%.s\n");
+ fprintf(fp, "\t$(CROSS_AS) $<\n\n");
+ fprintf(fp, "clean:\n");
+ fprintf(fp, "\trm -f $(OBJS) $(SRCS) syscall.a *~\n\n");
+ fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+ write_Z80_makefile();
+ write_Z80_call_table();
+ exit(0);
+}