From f2c4b6d8e1d7a18e047f78673340e89fdca09c43 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 26 Dec 2014 21:40:55 +0000 Subject: [PATCH] z88dk: Add first pieces to bootstrap Z88DK for Fuzix --- Library/Makefile | 1 + Library/tools/syscall-z88dk.c | 113 ++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Library/tools/syscall-z88dk.c diff --git a/Library/Makefile b/Library/Makefile index 8ad77aec..75ca3344 100644 --- a/Library/Makefile +++ b/Library/Makefile @@ -5,5 +5,6 @@ CFLAGS += -I../Kernel/include all: tools/syscall tools/binman tools/syscall: tools/syscall.c ../Kernel/include/syscall_name.h +tools/syscall-z88dk: tools/syscall-z88dk.c ../Kernel/include/syscall_name.h tools/binman: tools/binman.c diff --git a/Library/tools/syscall-z88dk.c b/Library/tools/syscall-z88dk.c new file mode 100644 index 00000000..9a266758 --- /dev/null +++ b/Library/tools/syscall-z88dk.c @@ -0,0 +1,113 @@ +/* + * Generate the syscall functions for Z88DK + * + * Z88DK has some "interesting" properties. It's SmallC derived + * so pushes the arguments backwards which we must cope with. It also + * has a nifty 'fastcall' HL single argument passing ABI that you can + * use (SDCC take notes please). + * + * We turn 2/3/4 argument syscalls into stack shuffles (in and out) and + * single argument into fastcall. + */ + +#include +#include +#include +#include "syscall_name.h" + +static char namebuf[128]; + +static void write_call(int n) +{ + FILE *fp; + snprintf(namebuf, 128, "z88dk/%s.asm", syscall_name[n]); + fp = fopen(namebuf, "w"); + if (fp == NULL) { + perror(namebuf); + exit(1); + } + fprintf(fp, "\tLIB syscall\n"); + fprintf(fp, "\tXLIB %s\n\n", syscall_name[n]); + fprintf(fp, ".%s\n", syscall_name[n]); + + switch(syscall_args[n]) { + case 0: + fprintf(fp, "\tld hl, %d\n", n); + fprintf(fp, "\tjp syscall\n"); + case 1: + fprintf(fp, "\tpush hl\n"); + fprintf(fp, "\tld hl, %d\n", n); + fprintf(fp, "\tcall syscall\n"); + fprintf(fp, "\tpop af\n"); + fprintf(fp, "\tret\n"); + break; + case 2: + fprintf(fp, "\tpop de\n\tpop bc\n\tpush de\n\tpush bc\n"); + fprintf(fp, "\tld hl, %d\n", n); + fprintf(fp, "\tcall syscall\n"); + fprintf(fp, "\tpop de\n\tpop bc\n\tpush de\n\tpush bc\n"); + fprintf(fp, "\tret\n"); + break; + case 3: + fprintf(fp, "\tpop de\n\tpop bc\n\tpop hl\n\tpush de\n\tpush bc\n\tpush hl\n"); + fprintf(fp, "\tld hl, %d\n", n); + fprintf(fp, "\tcall syscall\n"); + fprintf(fp, "\tpop de\n\tpop bc\n\tpop ix\n\tpush de\n\tpush bc\n\tpush ix\n"); + fprintf(fp, "\tret\n"); + break; + case 4: + fprintf(fp, "\tpop de\n\tpop bc\n\tpop hl\n\tpop ix\n\tpush de\n\tpush bc\n\tpush hl\n\tpush ix\n"); + fprintf(fp, "\tld hl, %d\n", n); + fprintf(fp, "\tcall syscall\n"); + fprintf(fp, "\tpop de\n\tpop bc\n\tpop ix\n\tpop iy\n\tpush de\n\tpush bc\n\tpush ix\n\tpush iy\n"); + fprintf(fp, "\tret\n"); + break; + } + fclose(fp); +} + +static void write_header(FILE *fp, int n) +{ + fprintf(fp, "extern int __LIB__ "); + if (syscall_args[n] == 1) + fprintf(fp, "__FASTCALL__ "); + fprintf(fp, "%s(", syscall_name[n]); + if (syscall_args[n] == 0) + fprintf(fp, "void);\n"); + if (syscall_args[n] == 1) + fprintf(fp, "unsigned int);\n"); + if (syscall_args[n] == 2) + fprintf(fp, "char *, unsigned int);\n"); + if (syscall_args[n] == 3) + fprintf(fp, "unsigned int, void *, unsigned int);\n"); + if (syscall_args[n] == 4) + fprintf(fp, "unsigned int, unsigned int, unsigned int, unsigned int);\n"); +} + + +static void write_call_table(void) +{ + int i; + for (i = 0; i < NR_SYSCALL; i++) + write_call(i); +} + +static void write_proto_header(void) +{ + int i; + FILE *fp = fopen("z88dk/header.proto", "w"); + if (fp == NULL) { + perror("z88dk/header.proto"); + exit(1); + } + for (i = 0; i < NR_SYSCALL; i++) + write_header(fp, i); + fclose(fp); +} + +int main(int argc, char *argv[]) +{ + write_proto_header(); + write_call_table(); + exit(0); +} -- 2.34.1