68000: very initial pieces to work on a first 680x0 port
authorAlan Cox <alan@linux.intel.com>
Fri, 30 Jan 2015 00:20:34 +0000 (00:20 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 30 Jan 2015 00:20:34 +0000 (00:20 +0000)
This is at the 'gee it compiled' stage.

18 files changed:
Kernel/platform-atarist/Makefile [new file with mode: 0644]
Kernel/platform-atarist/README [new file with mode: 0644]
Kernel/platform-atarist/config.h [new file with mode: 0644]
Kernel/platform-atarist/crt0.S [new file with mode: 0644]
Kernel/platform-atarist/devfd.c [new file with mode: 0644]
Kernel/platform-atarist/devfd.h [new file with mode: 0644]
Kernel/platform-atarist/device.h [new file with mode: 0644]
Kernel/platform-atarist/devices.c [new file with mode: 0644]
Kernel/platform-atarist/devlpr.c [new file with mode: 0644]
Kernel/platform-atarist/devlpr.h [new file with mode: 0644]
Kernel/platform-atarist/devlpr.s [new file with mode: 0644]
Kernel/platform-atarist/devtty.c [new file with mode: 0644]
Kernel/platform-atarist/devtty.h [new file with mode: 0644]
Kernel/platform-atarist/kernel.def [new file with mode: 0644]
Kernel/platform-atarist/libc.c [new file with mode: 0644]
Kernel/platform-atarist/main.c [new file with mode: 0644]
Kernel/platform-atarist/p68000.S [new file with mode: 0644]
Kernel/platform-atarist/tricks.S [new file with mode: 0644]

diff --git a/Kernel/platform-atarist/Makefile b/Kernel/platform-atarist/Makefile
new file mode 100644 (file)
index 0000000..fe51a1f
--- /dev/null
@@ -0,0 +1,34 @@
+
+CSRCS = devlpr.c devtty.c devfd.c
+CSRCS += devices.c main.c libc.c
+
+ASRCS = p68000.S crt0.S
+ASRCS += tricks.S
+
+COBJS = $(CSRCS:.c=$(BINEXT))
+AOBJS = $(ASRCS:.S=.o)
+OBJS  = $(COBJS) $(AOBJS)
+
+JUNK = $(CSRCS:.c=.o) $(ASRCS:.S=.o)
+
+all:   $(OBJS)
+
+$(COBJS): %.o: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+$(AOBJS): %.o: %.S
+       $(CROSS_AS) $(ASOPTS) $< -o $*.o
+
+clean:
+       rm -f $(OBJS) $(JUNK)  core *~ 
+
+image:
+       $(CROSS_LD) -M -o ../fuzix.bin \
+       crt0.o \
+       p68000.o ../start.o ../version.o ../lowlevel-68000.o \
+       tricks.o main.o ../timer.o ../kdata.o devfd.o devices.o \
+       ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+       ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../flat.o \
+       ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec32.o \
+       ../usermem_std-68000.o devlpr.o devtty.o libc.o ../vt.o ../malloc.o \
+       /usr/lib/gcc/m68k-linux-gnu/4.9.1/libgcc.a >../fuzix.map
diff --git a/Kernel/platform-atarist/README b/Kernel/platform-atarist/README
new file mode 100644 (file)
index 0000000..6d73366
--- /dev/null
@@ -0,0 +1,44 @@
+This is an initial 'gee it compiles' work in progress initial 68000 port
+
+Don't expect it to do anything !
+
+
+Notes:
+       Memory below $0800 is supervisor only (traps)
+
+Need to support 'resident' style binaries
+Start of disk boot block info ?
+
+Tidy up di/ei usage - we don't want to turn on hblank at random in our ei
+stuff!!!
+
+First boot sector loaded into buffer. must checksum to $1234
+then executed. Must be PI
+
+Eventually need multi-segment executables
+
+
+Interrupts
+
+2 - hblank
+4 - vblank
+6 - mfp (but is magic)
+
+$100 - mfp parallel
+$104 - mfp rs232 carrier det
+$108 - mfp rs232 cts
+$10c - mfp blitter done
+$110 - mfp timer d
+$114 - mfp timer c (200Hz)
+$118 - mfp midi/kbd
+$11c - floppy/hd req
+$120 - hblank counter (timer B)
+$124 - rs232 tx error
+$128 - rs232 tx empty
+$12c - rs232 rx error
+$130 - rs232 rx full
+$134 - mfp timer a
+$138 - rs232 ring det
+$13c - mono/colour detect
+
+
diff --git a/Kernel/platform-atarist/config.h b/Kernel/platform-atarist/config.h
new file mode 100644 (file)
index 0000000..1ad42c0
--- /dev/null
@@ -0,0 +1,43 @@
+/* Enable to make ^Z dump the inode table for debug */
+#undef CONFIG_IDUMP
+/* Enable to make ^A drop back into the monitor */
+#undef CONFIG_MONITOR
+/* Profil syscall support (not yet complete) */
+#undef CONFIG_PROFIL
+/* Multiple processes in memory at once */
+#define CONFIG_MULTI
+/* Single tasking - for now while we get it booting */
+#undef CONFIG_SINGLETASK
+/* 32bit with flat memory */
+#define CONFIG_FLAT
+#define CONFIG_32BIT
+#define CONFIG_BANKS   1               /* FIXME */
+#define CONFIG_USERMEM_DIRECT
+/* Video terminal, not a serial tty */
+#define CONFIG_VT
+/* Simple text mode */
+#define CONFIG_VT_SIMPLE
+/* Vt definitions */
+#define VT_BASE                (uint8_t *)0x6000       /* Default video text mode base */
+#define VT_WIDTH       32
+#define VT_HEIGHT      16
+#define VT_RIGHT       31
+#define VT_BOTTOM      15
+#define VT_INITIAL_LINE        4
+
+#define TICKSPERSEC 100   /* Ticks per second */
+
+#define BOOT_TTY (512 + 1)   /* Set this to default device for stdio, stderr */
+                          /* In this case, the default is the first TTY device */
+                            /* Temp FIXME set to serial port for debug ease */
+
+/* We need a tidier way to do this from the loader */
+#define CMDLINE        NULL      /* Location of root dev name */
+
+/* Device parameters */
+#define NUM_DEV_TTY 2
+#define NDEVS    2        /* Devices 0..NDEVS-1 are capable of being mounted */
+                          /*  (add new mountable devices to beginning area.) */
+#define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
+#define NBUFS    10       /* Number of block buffers */
+#define NMOUNTS         4        /* Number of mounts at a time */
diff --git a/Kernel/platform-atarist/crt0.S b/Kernel/platform-atarist/crt0.S
new file mode 100644 (file)
index 0000000..5553713
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ *     Need to wipe BSS etc once we figure out our preferred boot method
+ */
+               .globl _start
+
+.mri 1
+
+_start:
+               or #$0700,sr
+               /* FIXME: hard coded ugly */
+               move.l uarea_block+508,a7
+               jsr init_early
+               jsr init_hardware
+               jsr fuzix_main
+               or #$0700,sr
+stop:          bra stop
diff --git a/Kernel/platform-atarist/devfd.c b/Kernel/platform-atarist/devfd.c
new file mode 100644 (file)
index 0000000..9a29772
--- /dev/null
@@ -0,0 +1,124 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devfd.h>
+
+#define MAX_FD 4
+
+#define OPDIR_NONE     0
+#define OPDIR_READ     1
+#define OPDIR_WRITE    2
+
+#define FD_READ                0x88    /* 2797 needs 0x88, 1797 needs 0x80 */
+#define FD_WRITE       0xA8    /* Likewise A8 v A0 */
+
+static uint8_t motorct;
+static uint8_t fd_selected = 0xFF;
+static uint8_t fd_tab[MAX_FD];
+
+static void fd_motor_busy(void)
+{
+    motorct++;
+}
+
+static void fd_motor_idle(void)
+{
+    motorct--;
+    // if (motorct == 0) ... start timer */
+}
+
+static void fd_motor_timeout(void)
+{
+    fd_selected = 0xff;
+//    fd_motor_off();
+}
+
+/*
+ *     We only support normal block I/O because otherwise we'd need
+ *     bounce buffers - which would make it just as pointless!
+ *
+ *     The Dragon and COCO have 18 x 256 byte sectors per track. We
+ *     use them in pairs. We assume an even sectors per track. This is fine
+ *     for our usage but would break for single density media.
+ */
+
+/* static uint8_t selmap[4] = { 0x01, 0x02, 0x04, 0x40 }; - COCO */
+static uint8_t selmap[4] = {0x00, 0x01, 0x02, 0x03 };
+
+static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
+{
+    blkno_t block;
+    uint32_t dptr;
+    int ct = 0;
+    int tries;
+    uint8_t err;
+    uint8_t *driveptr = fd_tab + minor;
+    uint8_t cmd[6];
+
+    if(rawflag)
+        goto bad2;
+
+    fd_motor_busy();           /* Touch the motor timer first so we don't
+                                   go and turn it off as we are doing this */
+    if (fd_selected != minor) {
+//        uint8_t err = fd_motor_on(selmap[minor]);
+//        if (err)
+//            goto bad;
+    }
+
+    dptr = (uint32_t)udata.u_buf->bf_data;
+    block = udata.u_buf->bf_blk;
+
+//    kprintf("Issue command: drive %d\n", minor);
+    cmd[0] = is_read ? FD_READ : FD_WRITE;
+    cmd[1] = block / 9;                /* 2 sectors per block */
+    cmd[2] = ((block % 9) << 1) + 1;   /*eww.. */
+    cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE;
+    cmd[4] = dptr >> 8;
+    cmd[5] = dptr & 0xFF;
+        
+    while (ct < 2) {
+        for (tries = 0; tries < 4 ; tries++) {
+//            err = fd_operation(cmd, driveptr);
+//            if (err == 0)
+//                break;
+//            if (tries > 1)
+//                fd_reset(driveptr);
+        }
+        /* FIXME: should we try the other half and then bale out ? */
+        if (tries == 3)
+            goto bad;
+        cmd[4]++;      /* Move on 256 bytes in the buffer */
+        cmd[2]++;      /* Next sector for 2nd block */
+        ct++;
+    }
+    fd_motor_idle();
+    return 1;
+bad:
+    kprintf("fd%d: error %x\n", minor, err);
+bad2:
+    fd_motor_idle();
+    udata.u_error = EIO;
+    return -1;
+
+}
+
+int fd_open(uint8_t minor, uint16_t flag)
+{
+    if(minor >= MAX_FD) {
+        udata.u_error = ENODEV;
+        return -1;
+    }
+    return 0;
+}
+
+int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    return fd_transfer(minor, true, rawflag);
+}
+
+int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    return fd_transfer(minor, false, rawflag);
+}
+
diff --git a/Kernel/platform-atarist/devfd.h b/Kernel/platform-atarist/devfd.h
new file mode 100644 (file)
index 0000000..e5224ac
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __DEVFD_DOT_H__
+#define __DEVFD_DOT_H__
+
+/* public interface */
+int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int fd_open(uint8_t minor, uint16_t flag);
+
+/* low level interface */
+uint8_t fd_reset(uint8_t *drive);
+uint8_t fd_operation(uint8_t *cmd, uint8_t *drive);
+uint8_t fd_motor_on(uint8_t drive);
+uint8_t fd_motor_off(void);
+
+#endif /* __DEVFD_DOT_H__ */
+
diff --git a/Kernel/platform-atarist/device.h b/Kernel/platform-atarist/device.h
new file mode 100644 (file)
index 0000000..6f4c1e2
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __DEVICE_DOT_H__
+#define __DEVICE_DOT_H__
+
+extern void mod_control(uint8_t set, uint8_t clr);
+
+#endif /* __DEVICE_DOT_H__ */
diff --git a/Kernel/platform-atarist/devices.c b/Kernel/platform-atarist/devices.c
new file mode 100644 (file)
index 0000000..fe99fe2
--- /dev/null
@@ -0,0 +1,39 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <devfd.h>
+#include <devsys.h>
+#include <devlpr.h>
+#include <tty.h>
+#include <vt.h>
+
+struct devsw dev_tab[] =  /* The device driver switch table */
+{
+// minor    open         close        read      write       ioctl
+// -----------------------------------------------------------------
+  /* 0: /dev/fd                Floppy disc block devices  */
+  {  fd_open,     no_close,    fd_read,   fd_write,   no_ioctl },
+  /* 1: /dev/hd                Hard disc block devices (absent) */
+  {  nxio_open,     no_close,    no_rdwr,   no_rdwr,   no_ioctl },
+  /* 2: /dev/tty       TTY devices */
+  {  tty_open,     tty_close,   tty_read,  tty_write,  vt_ioctl },
+  /* 3: /dev/lpr       Printer devices */
+  {  lpr_open,     lpr_close,   no_rdwr,   lpr_write,  no_ioctl  },
+  /* 4: /dev/mem etc   System devices (one offs) */
+  {  no_open,      no_close,    sys_read, sys_write, sys_ioctl  },
+  /* Pack to 7 with nxio if adding private devices and start at 8 */
+};
+
+bool validdev(uint16_t dev)
+{
+    /* This is a bit uglier than needed but the right hand side is
+       a constant this way */
+    if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) + 255)
+       return false;
+    else
+        return true;
+}
+void device_init(void)
+{
+}
+
diff --git a/Kernel/platform-atarist/devlpr.c b/Kernel/platform-atarist/devlpr.c
new file mode 100644 (file)
index 0000000..a0cb189
--- /dev/null
@@ -0,0 +1,47 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <device.h>
+#include <devlpr.h>
+
+/* random test places */
+uint8_t *lpstat = (uint8_t *)0xFF00;
+uint8_t *lpdata = (uint8_t *)0xFF01;
+
+int lpr_open(uint8_t minor, uint16_t flag)
+{
+       return 0;
+}
+
+int lpr_close(uint8_t minor)
+{
+       return 0;
+}
+
+int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+       int c = udata.u_count;
+       unsigned char *p = udata.u_base;
+       uint16_t ct;
+
+       while (c-- > 0) {
+               ct = 0;
+
+               /* Try and balance polling and sleeping */
+               while (*lpstat & 2) {
+                       ct++;
+                       if (ct == 10000) {
+                               udata.u_ptab->p_timeout = 3;
+                               if (psleep_flags(NULL, flag)) {
+                                       if (udata.u_count)
+                                               udata.u_error = 0;
+                                       return udata.u_count;
+                               }
+                               ct = 0;
+                       }
+               }
+               /* Data */
+               *lpdata = ugetc(p++);
+       }
+       return udata.u_count;
+}
diff --git a/Kernel/platform-atarist/devlpr.h b/Kernel/platform-atarist/devlpr.h
new file mode 100644 (file)
index 0000000..7765c18
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __DEVLPR_DOT_H__
+#define __DEVLPR_DOT_H__
+
+int lpr_open(uint8_t minor, uint16_t flag);
+int lpr_close(uint8_t minor);
+int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+
+#endif
diff --git a/Kernel/platform-atarist/devlpr.s b/Kernel/platform-atarist/devlpr.s
new file mode 100644 (file)
index 0000000..a4c4be4
--- /dev/null
@@ -0,0 +1,86 @@
+
+;;; gcc for m6809 : Oct  1 2014 11:32:32
+;;; 4.6.4 (gcc6809lw)
+;;; ABI version 1
+;;; -mint16
+       .module devlpr.c
+       .area .text2
+       .globl _lpr_open
+_lpr_open:
+       pshs    u
+       leau    ,s
+       ldx     #0
+       puls    u,pc
+       .globl _lpr_close
+_lpr_close:
+       pshs    u
+       leau    ,s
+       ldx     #0
+       puls    u,pc
+       .globl _lpr_write
+_lpr_write:
+       pshs    y,u
+       leas    -6,s
+       leau    ,s
+       ldy     _udata+96
+       ldx     _udata+94
+       stx     2,u
+       cmpy    #0      ;cmphi:
+       ble     L8
+       leay    -1,y
+       sty     4,u
+L14:
+       ldb     [_lpstat]
+       clra            ;zero_extendqihi: R:b -> R:d
+       std     ,u
+       anda #0
+       andb #2
+       cmpd    #0      ;cmphi:
+       beq     L16
+       ldy     _udata
+       ldd     #3
+       std     36,y
+       ldb     13,u
+       ldx     #0
+       jsr     __far_call_handler      ;old style
+               .dw     _psleep_flags
+               .db     
+       cmpx    #0      ;cmphi:
+       beq     L14
+       ldy     _udata+96
+       beq     L8
+       ldd     #0
+       std     _udata+12
+L8:
+       leax    ,y
+       leas    6,s
+       puls    y,u,pc
+L16:
+       ldy     _lpdata
+       ldx     2,u
+       leax    1,x
+       stx     ,u
+       ldx     2,u
+       jsr     __far_call_handler      ;old style
+               .dw     _ugetc
+               .db     
+       tfr     x,d
+       stb     ,y      ;movlsbqihi: R:d -> ,y
+       ldx     4,u
+       leax    -1,x
+       stx     4,u
+       cmpx    #-1     ;cmphi:
+       beq     L17
+       ldx     ,u
+       stx     2,u
+       jmp     L14
+L17:
+       ldy     _udata+96
+       bra     L8
+       .globl _lpdata
+       .area .data
+_lpdata:
+       .word   -255
+       .globl _lpstat
+_lpstat:
+       .word   -256
diff --git a/Kernel/platform-atarist/devtty.c b/Kernel/platform-atarist/devtty.c
new file mode 100644 (file)
index 0000000..de7b760
--- /dev/null
@@ -0,0 +1,189 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <vt.h>
+#include <tty.h>
+
+#undef  DEBUG                  /* UNdefine to delete debug code sequences */
+
+uint8_t *uart_data = (uint8_t *)0xFF04;        /* ACIA data */
+uint8_t *uart_status = (uint8_t *)0xFF05;      /* ACIA status */
+uint8_t *uart_command = (uint8_t *)0xFF06;     /* ACIA command */
+uint8_t *uart_control = (uint8_t *)0xFF07;     /* ACIA control */
+
+unsigned char tbuf1[TTYSIZ];
+unsigned char tbuf2[TTYSIZ];
+
+struct s_queue ttyinq[NUM_DEV_TTY + 1] = {     /* ttyinq[0] is never used */
+       {NULL, NULL, NULL, 0, 0, 0},
+       {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2},
+       {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2}
+};
+
+/* tty1 is the screen tty2 is the serial port */
+
+/* Output for the system console (kprintf etc) */
+void kputchar(char c)
+{
+       if (c == '\n')
+               tty_putc(1, '\r');
+       tty_putc(1, c);
+}
+
+bool tty_writeready(uint8_t minor)
+{
+       uint8_t c;
+       if (minor == 1)
+               return 1;
+       c = *uart_status;
+       return c & 16;  /* TX DATA empty */
+}
+
+/* For DragonPlus we should perhaps support both monitors 8) */
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+       if (minor == 1) {
+               vtoutput(&c, 1);
+       } else
+               *uart_data = c; /* Data */
+}
+
+void tty_setup(uint8_t minor)
+{
+       if (minor == 2) {
+               /* FIXME: do proper mode setting */
+               *uart_command = 0x01;   /* DTR high, IRQ enabled, TX irq disabled 8N1 */
+               *uart_control = 0x1E;   /* 9600 baud */
+       }
+}
+
+int tty_carrier(uint8_t minor)
+{
+       /* The serial DCD is status bit 5 but not wired */
+       return 1;
+}
+
+void tty_interrupt(void)
+{
+       uint8_t r = *uart_status;
+       if (r & 0x8) {
+               r = *uart_data;
+               tty_inproc(2,r);
+       }       
+}
+
+uint8_t keymap[8];
+static uint8_t keyin[8];
+static uint8_t keybyte, keybit;
+static uint8_t newkey;
+static int keysdown = 0;
+static uint8_t shiftmask[8] = {
+       0, 0x40, 0, 0, 0, 0, 0, 0x40
+};
+
+static uint8_t rbit[8] = {
+       0xFE,
+       0xFD,
+       0xFB,
+       0xF7,
+       0xEF,
+       0xDF,
+       0xBF,
+       0x7F,
+};
+
+/* Row inputs: multiplexed with the joystick */
+static volatile uint8_t *pia_row = (uint8_t *)0xFF00;
+/* Columns for scanning: multiplexed with the printer port */
+static volatile uint8_t *pia_col = (uint8_t *)0xFF02;
+/* Control */
+static volatile uint8_t *pia_ctrl = (uint8_t *)0xFF03;
+
+static void keyproc(void)
+{
+       int i;
+       uint8_t key;
+
+       for (i = 0; i < 8; i++) {
+               /* We do the scan in software on the Dragon */
+               *pia_col = rbit[i];
+               keyin[i] = ~*pia_row;
+               key = keyin[i] ^ keymap[i];
+               if (key) {
+                       int n;
+                       int m = 1;
+                       for (n = 0; n < 7; n++) {
+                               if ((key & m) && (keymap[i] & m)) {
+                                       if (!(shiftmask[i] & m))
+                                               keysdown--;
+                               }
+                               if ((key & m) && !(keymap[i] & m)) {
+                                       if (!(shiftmask[i] & m))
+                                               keysdown++;
+                                       keybyte = i;
+                                       keybit = n;
+                                       newkey = 1;
+                               }
+                               m += m;
+                       }
+               }
+               keymap[i] = keyin[i];
+       }
+}
+
+uint8_t keyboard[8][7] = {
+       { '0', '8', '@', 'h', 'p', 'x', 10 },
+       { '1', '9', 'a', 'i', 'q', 'y', 0 /* clear - used as ctrl*/ },
+       { '2', ':', 'b', 'j', 'r', 'z', 27 /* break (used for esc) */ },
+       { '3', ';', 'c', 'k', 's', '^' /* up */, 0 /* NC */ },
+       { '4', ',', 'd', 'l', 't', '|' /* down */, 0 /* NC */ },
+       { '5', '-', 'e', 'm', 'u', 8 /* left */, 0 /* NC */ },
+       { '6', '.', 'f', 'n', 'v', '\t' /* right */, 0 /* NC */ },
+       { '7', '/', 'g', 'o', 'w', ' ', 0 /* shift */ },
+};
+
+uint8_t shiftkeyboard[8][7] = {
+       { '_', '(', '\\', 'H', 'P', 'X', 10 },
+       { '!', ')', 'A', 'I', 'Q', 'Y', 0 /* clear */ },
+       { '"', '*', 'B', 'J', 'R', 'Z', 3 /* break */ },
+       { '#', '+', 'C', 'K', 'S', '[' /* up */, 0 /* NC */ },
+       { '$', '<', 'D', 'L', 'T', ']' /* down */, 0 /* NC */ },
+       { '%', '=', 'E', 'M', 'U', '{' /* left */, 0 /* NC */ },
+       { '&', '>', 'F', 'N', 'V', '}' /* right */, 0 /* NC */ },
+       { '\'', '?', 'G', 'O', 'W', ' ', 0 /* shift */ },
+};
+
+static void keydecode(void)
+{
+       uint8_t c;
+
+       if (keymap[7] & 64)     /* shift */
+               c = shiftkeyboard[keybyte][keybit];
+       else
+               c = keyboard[keybyte][keybit];
+       if (keymap[1] & 64) {   /* control */
+               if (c > 31 && c < 96)
+                       c &= 31;
+       }
+       tty_inproc(1, c);
+}
+
+void platform_interrupt(void)
+{
+       uint8_t i = *pia_ctrl;
+       if (i & 0x80) {
+               *pia_col;
+               newkey = 0;
+               keyproc();
+               if (keysdown < 3 && newkey)
+                       keydecode();
+               timer_interrupt();
+       }
+}
+
+/* This is used by the vt asm code, but needs to live at the top of the kernel */
+uint16_t cursorpos;
diff --git a/Kernel/platform-atarist/devtty.h b/Kernel/platform-atarist/devtty.h
new file mode 100644 (file)
index 0000000..14c28c3
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __DEVTTY_DOT_H__
+#define __DEVTTY_DOT_H__
+
+#define KEY_ROWS 8
+#define KEY_COLS 7
+extern uint8_t keymap[8];
+extern uint8_t keyboard[8][7];
+extern uint8_t shiftkeyboard[8][7];
+
+#endif
diff --git a/Kernel/platform-atarist/kernel.def b/Kernel/platform-atarist/kernel.def
new file mode 100644 (file)
index 0000000..c14daee
--- /dev/null
@@ -0,0 +1,22 @@
+; UZI mnemonics for memory addresses etc
+
+U_DATA                      equ 0x7D00       ; (this is struct u_data from kernel.h)
+U_DATA__TOTALSIZE           equ 0x300        ; 256+256+256 bytes.
+
+
+SAM_USER macro
+       sta 0xFFD4
+       endm
+
+SAM_KERNEL macro
+       sta 0xFFD5
+       endm
+
+SAM_SAVE macro
+       ldy 4
+       endm
+
+SAM_RESTORE macro
+       sta ,y
+       endm
+
diff --git a/Kernel/platform-atarist/libc.c b/Kernel/platform-atarist/libc.c
new file mode 100644 (file)
index 0000000..e718087
--- /dev/null
@@ -0,0 +1,40 @@
+#include "cpu.h"
+
+void *memcpy(void *d, const void *s, size_t sz)
+{
+  unsigned char *dp = d;
+  const unsigned char *sp = s;
+  while(sz--)
+    *dp++=*sp++;
+  return d;
+}
+
+void *memset(void *d, int c, size_t sz)
+{
+  unsigned char *p = d;
+  while(sz--)
+    *p++ = c;
+  return d;
+}
+
+size_t strlen(const char *p)
+{
+  const char *e = p;
+  while(*e++);
+  return e-p-1;
+}
+
+int memcmp(const void *a, const void *b, size_t n)
+{
+  const uint8_t *ap = a;
+  const uint8_t *bp = b;
+  while(n--) {
+    if (*ap < *bp)
+      return -1;
+    if (*ap != *bp)
+      return 1;
+    ap++;
+    bp++;
+  }
+  return 0;
+}
diff --git a/Kernel/platform-atarist/main.c b/Kernel/platform-atarist/main.c
new file mode 100644 (file)
index 0000000..057f131
--- /dev/null
@@ -0,0 +1,37 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+
+void platform_idle(void)
+{
+}
+
+void do_beep(void)
+{
+}
+
+/*
+ * Map handling: We have flexible paging. Each map table consists of a set of pages
+ * with the last page repeated to fill any holes.
+ */
+
+void pagemap_init(void)
+{
+}
+
+void map_init(void)
+{
+}
+
+unsigned char vt_mangle_6847(unsigned char c)
+{
+       if (c >= 96)
+               c -= 32;
+       c &= 0x3F;
+       return c;
+}
+
+u_block uarea_block[PTABSIZE];
+uaddr_t ramtop;
\ No newline at end of file
diff --git a/Kernel/platform-atarist/p68000.S b/Kernel/platform-atarist/p68000.S
new file mode 100644 (file)
index 0000000..83db99e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *         68000 Atari ST
+ *
+ *     We need pretty much nothing here as we don't do page mapping.
+ */
+
+               .globl trap_reboot
+               .globl init_early
+               .globl init_hardware
+               .globl program_vectors
+               .globl outchar
+               .globl trap_reboot, trap_monitor
+.mri 1
+trap_reboot:
+trap_monitor:
+           or #0700,sr
+           bra trap_monitor
+init_early:
+            rts
+
+init_hardware:
+            ; set system RAM size
+           move.w #512,ramsize
+           move.w #448,procmem ; guesses for now
+            rts
+
+
+;      Nothing to do in 68000 - all set up once at boot
+;
+program_vectors:
+           rts
+
+;
+;      All mapped all the time
+;
+map_process_always:
+map_process:
+map_kernel:
+map_restore:
+map_save:
+           rts
+
+; outchar: Wait for UART TX idle, then print the char in d0
+
+outchar:
+           move.w d0,-(sp)
+outcharw:
+           move.b $FFFFFA13,d0
+           btst #2,d0
+           beq outcharw
+           move.w (sp)+,d0
+           move.b d0,$FFFFFA2D
+           rts
+       
+.section data
+
+_kernel_flag: byte 1
diff --git a/Kernel/platform-atarist/tricks.S b/Kernel/platform-atarist/tricks.S
new file mode 100644 (file)
index 0000000..a1cf71c
--- /dev/null
@@ -0,0 +1,140 @@
+#include "../kernel-68000.def"
+
+
+.globl switchout,switchin,dofork
+
+.mri 1
+
+; Switchout switches out the current process, finds another that is READY,
+; possibly the same process, and switches it in.  When a process is
+; restarted after calling switchout, it thinks it has just returned
+; from switchout().
+; 
+; This function can have no arguments or auto variables.
+switchout:
+        or #$0700,sr
+        bsr chksigs
+        ; save machine state
+
+        clr.w -(sp) ; return code set here is ignored, but _switchin can 
+        ; return from either _switchout OR _dofork, so they must both write 
+        ; U_DATA__U_SP with the following on the stack:
+       movem.l a0-a4/a6/d0-d7,-(sp)    ; FIXME: trim to callee saves
+       move.l sp,U_DATA__U_SP(a5)      ; this is where the SP is restored in _switchin
+
+        ; set inint to false
+        clr.b inint
+
+        ; find another process to run (may select this one again)
+        bsr getproc
+
+               move.l a0,-(sp)         ; CHECK compiler call/return rules
+        bsr switchin
+
+        ; we should never get here
+        jmp trap_monitor
+
+badswitchmsg: ascii "_switchin: FAIL"
+            byte 13,10,0
+swapped: ascii "_switchin: SWAPPED"
+            byte 13,10,0
+
+switchin:
+        or #$0700,sr
+       move.l 4(sp),a0         ; task to switch to
+       move.l P_TAB__P_UDATA_OFFSET(a0),a5
+
+        ; check u_data->u_ptab matches what we wanted
+       move.l 4(sp),d0
+       cmp.l U_DATA__U_PTAB(a5),d0
+       bne switchinfail
+
+       ; wants optimising up a bit
+       move.b #P_RUNNING,P_TAB__P_STATUS_OFFSET(a0)
+
+        ; runticks = 0
+       clr.w runticks
+
+        ; restore machine state -- note we may be returning from either
+        ; _switchout or _dofork
+        move.l U_DATA__U_SP(a5),sp
+       movem.l (sp)+,a0-a4/a6/d0-d7    ; FIXME: trim to callee saves here too
+       add #2,sp                       ; drop return code dummy
+
+        tst.b inint
+        beq keepoff ; in ISR, leave interrupts off
+        and #$F8FF,sr
+keepoff:
+        rts ; return with interrupts on
+
+switchinfail:
+       bsr outa0hex
+        lea badswitchmsg,a0
+        bsr outstring
+       ; something went wrong and we didn't switch in what we asked for
+        bra trap_monitor
+
+
+;
+;      Called from _fork. We are in a syscall, the uarea is live as the
+;      parent uarea. The kernel is the mapped object.
+;
+;      We don't support fork() proper only vfork()
+;
+dofork:
+        ; always disconnect the vehicle battery before performing maintenance
+        or #$0700,sr ; should already be the case ... belt and braces.
+
+       move.l 4(sp),a0
+       move.l a0,fork_proc_ptr
+
+        ; prepare return value in parent process -- HL = p->p_pid;
+       move.w P_TAB__P_PID_OFFSET(a0),d0
+       move.w d0,-(sp)
+       movem.l a0-a6/d0-d7,-(sp)               ; FIXME - callees !
+
+        ; save kernel stack pointer -- when it comes back in the parent we'll be in
+        ; _switchin which will immediately return (appearing to be _dofork()
+       ; returning) and with HL (ie return code) containing the child PID.
+        ; Hurray.
+
+        move.l sp,U_DATA__U_SP(a5)
+       move.l a5,P_TAB__P_UDATA_OFFSET(a0)
+
+        ; now we're in a safe state for _switchin to return in the parent
+       ; process.
+
+       ; FIXME: allocation heap walk/copy for chains
+
+       bsr bankfork                    ;       do the bank to bank copy
+
+       ; Returns with a5 set for the new process
+
+        ; now the copy operation is complete we can get rid of the stuff
+        ; _switchin will be expecting from our copy of the stack.
+
+       add.l #58,sp                    ; FIXME: adjut when adjust movem's
+
+        ; Make a new process table entry, etc.
+        move.l fork_proc_ptr,-(sp)
+        jsr newproc
+        add.l #4,sp
+
+        clr.w runticks
+        ; in the child process, fork() returns zero.
+       clr.w d0
+       ;
+       ; And we exit, with the kernel mapped, the child now being deemed
+       ; to be the live uarea. The parent is frozen in time and space as
+       ; if it had done a switchout().
+        rts
+
+;
+;      This is related so we will keep it here. Copy the process memory
+;      for a fork. Walk the heap allocations for this process and duplicate
+;      them. We need to allow this to fail and ripple the error back nicely
+;
+bankfork:
+       rts
+
+fork_proc_ptr: long 0 ; (C type is struct p_tab *) -- address of child process p_tab entry