From: Alan Cox Date: Fri, 30 Jan 2015 00:20:34 +0000 (+0000) Subject: 68000: very initial pieces to work on a first 680x0 port X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=ad17f69f5f0afad42ae7a6cddf156da9bd498f25;p=FUZIX.git 68000: very initial pieces to work on a first 680x0 port This is at the 'gee it compiled' stage. --- diff --git a/Kernel/platform-atarist/Makefile b/Kernel/platform-atarist/Makefile new file mode 100644 index 00000000..fe51a1f9 --- /dev/null +++ b/Kernel/platform-atarist/Makefile @@ -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 index 00000000..6d733665 --- /dev/null +++ b/Kernel/platform-atarist/README @@ -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 index 00000000..1ad42c08 --- /dev/null +++ b/Kernel/platform-atarist/config.h @@ -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 index 00000000..5553713a --- /dev/null +++ b/Kernel/platform-atarist/crt0.S @@ -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 index 00000000..9a29772a --- /dev/null +++ b/Kernel/platform-atarist/devfd.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#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 index 00000000..e5224ac9 --- /dev/null +++ b/Kernel/platform-atarist/devfd.h @@ -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 index 00000000..6f4c1e26 --- /dev/null +++ b/Kernel/platform-atarist/device.h @@ -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 index 00000000..fe99fe2c --- /dev/null +++ b/Kernel/platform-atarist/devices.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000..a0cb189d --- /dev/null +++ b/Kernel/platform-atarist/devlpr.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +/* 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 index 00000000..7765c187 --- /dev/null +++ b/Kernel/platform-atarist/devlpr.h @@ -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 index 00000000..a4c4be44 --- /dev/null +++ b/Kernel/platform-atarist/devlpr.s @@ -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 index 00000000..de7b760b --- /dev/null +++ b/Kernel/platform-atarist/devtty.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 00000000..14c28c31 --- /dev/null +++ b/Kernel/platform-atarist/devtty.h @@ -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 index 00000000..c14daee9 --- /dev/null +++ b/Kernel/platform-atarist/kernel.def @@ -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 index 00000000..e718087e --- /dev/null +++ b/Kernel/platform-atarist/libc.c @@ -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 index 00000000..057f131f --- /dev/null +++ b/Kernel/platform-atarist/main.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +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 index 00000000..83db99ef --- /dev/null +++ b/Kernel/platform-atarist/p68000.S @@ -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 index 00000000..a1cf71c6 --- /dev/null +++ b/Kernel/platform-atarist/tricks.S @@ -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