syscall-scc6809: generate syscalls for 6809 with scc
authorAlan Cox <alan@linux.intel.com>
Wed, 29 Jun 2016 11:35:52 +0000 (12:35 +0100)
committerAlan Cox <alan@linux.intel.com>
Wed, 29 Jun 2016 11:35:52 +0000 (12:35 +0100)
First attempt

Library/tools/syscall-scc6809.c [new file with mode: 0644]

diff --git a/Library/tools/syscall-scc6809.c b/Library/tools/syscall-scc6809.c
new file mode 100644 (file)
index 0000000..e14e2c6
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *     Generate the syscall functions for Z88DK
+ *
+ *     SCC has some "interesting" properties. It's SmallC derived so pushes
+ *     the arguments backwards which we must cope with while the kernel API
+ *     carefully matches the gcc API of argument 1 in x and the other
+ *     arguments on the stack offset as needed for the caller of the syscall
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "syscall_name.h"
+
+static char namebuf[128];
+
+static void write_call(int n)
+{
+  FILE *fp;
+  snprintf(namebuf, 128, "fuzix-scc6809/%s.s", syscall_name[n]);
+  fp = fopen(namebuf, "w");
+  if (fp == NULL) {
+    perror(namebuf);
+    exit(1);
+  }
+  
+  fprintf(fp, "\t.text\n");
+  fprintf(fp, "\t.extern __syscall\n");
+  fprintf(fp, "\t.globl %s\n\n", syscall_name[n]);
+  fprintf(fp, "%s:\n", syscall_name[n]);
+
+  if (syscall_args[n] == VARARGS) {
+    /* Icky but there are only 3 and all are 2 v 3 arg */
+    fprintf(fp, "\tcmpu #2\n");
+    fprintf(fp, "\tbne l1\n");
+    fprintf(fp, "\tpuls d,x,u\n");
+    fprintf(fp, "\texg x,u\n");
+    fprintf(fp, "\tpshs d,x,u\n");
+    fprintf(fp, "\tldx 6,s\n");
+    fprintf(fp, "\tldd #%d\n", n);
+    fprintf(fp, "\tjmp __syscall\n");
+    fprintf(fp, "l1:\n");
+    fprintf(fp, "\tpuls d,x,y,u\n");
+    fprintf(fp, "\texg x,u\n");
+    fprintf(fp, "\tpshs d,x,y,u\n");
+    fprintf(fp, "\tldx 8,s\n");
+    fprintf(fp, "\tldd #%d\n", n);
+    fprintf(fp, "\tjmp __syscall\n");
+    fclose(fp);
+    return;
+  }
+
+  switch(syscall_args[n]) {
+    case 0:
+      break;
+    case 1:
+      fprintf(fp, "\tldx 2,s\n");
+      break;
+    case 2:
+      fprintf(fp, "\tldx 4,s\n");
+      break;
+    case 3:
+      fprintf(fp, "\tpuls d,x,u\n");
+      fprintf(fp, "\texg x,u\n");
+      fprintf(fp, "\tpshs d,x,u\n");
+      fprintf(fp, "\tldx 6,s\n");
+      break;
+    case 4:
+      fprintf(fp, "\tpuls d,x,y,u\n");
+      fprintf(fp, "\texg x,u\n");
+      fprintf(fp, "\tpshs d,x,y,u\n");
+      fprintf(fp, "\tldx 8,s\n");
+  }
+  fprintf(fp, "\tldd #%d\n", n);
+  fprintf(fp, "\tjmp __syscall\n");
+  fclose(fp);
+}
+
+static void write_call_table(void)
+{
+  int i;
+  for (i = 0; i < NR_SYSCALL; i++)
+    write_call(i);
+}
+
+static void write_makefile(void)
+{
+  int i;
+  FILE *fp = fopen("fuzix-scc6809/Makefile", "w");
+  if (fp == NULL) {
+    perror("Makefile");
+    exit(1);
+  }
+  fprintf(fp, "# Autogenerated by tools/syscall-scc6809\n");
+  fprintf(fp, "CROSS_AS=lxas09\nCROSS_LD=lxld09\nCROSS_AR=lxar\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]);
+  fprintf(fp, "\n\nASRCALL = $(ASRCS) $(ASYS)\n");
+  fprintf(fp, "\nAOBJS = $(ASRCALL:.s=.o)\n\n");
+  fprintf(fp, "syslib.lib: $(AOBJS)\n");
+  fprintf(fp, "\techo $(AOBJS) >syslib.l\n");
+  fprintf(fp, "\t$(CROSS_AR) rc syslib.lib $(AOBJS)\n\n");
+  fprintf(fp, "$(AOBJS): %%.o: %%.s\n");
+  fprintf(fp, "\t$(CROSS_AS) $(ASOPTS) -o $*.o $<\n\n");
+  fprintf(fp, "clean:\n");
+  fprintf(fp, "\trm -f $(AOBJS) $(ASRCS) syslib.lib syslib.l *~\n\n");
+  fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+  write_makefile();
+  write_call_table();
+  exit(0);
+}