[comp.os.minix] ST MINIX 1.5.5 crc problems, and general comments

SA44%liverpool.ac.uk@nsfnet-relay.ac.uk (Kevin Maguire) (03/21/90)

I've just applied Frans' ST 1.5.5 patches. I got some patch failures and
some (offset) messages. The failures I knew about cos I'd done a little
'tuning' i.e. speeded up a few routines in stvdu.c, by replacing then with
assembly language, faster screen scrolling etc. However, the offsets
in stmain.c & stmpx.s puzzled me.
  So, I got my original MINIX 1.1 sources out, re-applied the 1.5.0 patches,
worked fine. Then reapplied the 1.5.5 patches... The patch failures, of
course, were gone, but still stmain.c & stmpx.s patched with lines that
were offset!!! I checked against Frans' crc's and lo and be-hold stmain.c
and stmpx.s failed, as did 6 files in lib/atari (no not stcatch.s).
   Has anyone else had these problems??? Or Frans' could you explain them?

On a different note, I'm very pleased with the speed improvment from 1.1
to 1.5.5, except WHY IS THE KEYBOARD SOOOOOO SLUGISH?????
1.5.5 seems okay on the PC so I presume it must be the ST's keyboard
device driver that's causing some sort of bottle-neck, anyone comment?

Also, de crashes rather strangely after about 1 minutes use. It produces that
old ST minix favourite 'segmentation violation', but rather strangely the
PC value is in the kernel??

signal=11 pid=0 pc=79E

It always seems to happen after the minute and I've never seen it happen
with any other command, kernel problem???

NSFnet: sa44%liv.ac.uk@nsfnet-relay.ac.uk
JANET:  sa44@uk.ac.liv

meulenbr@cstw68.prl.philips.nl (Frans Meulenbroeks) (03/22/90)

I've never seen your de problem.
Maybe you should chmem more memory to it (always a good idea).
It could also be your kernel, due to a wrong stmpx.s or stmain.c
Maybe I goofed with the diffs. Maybe you missed a posting.
I'll include both these files at the end.

I'll look at the keyboard problem. 

regards, Frans.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	kernel/stmain.c
#	kernel/stmpx.s
# This archive created: Thu Mar 22 09:13:30 1990
sed 's/^X//' << \SHAR_EOF > kernel/stmain.c
X#if (CHIP == M68000)
X/* This file contains the main program of MINIX for the Atari ST.
X * The routine main() initializes the system and starts the ball
X * rolling by setting up the proc table, interrupt vectors, and
X * scheduling each task to run to initialize itself.
X * 
X * The entries into this file are:
X *   main:		MINIX main program
X *   none:		called for an interrupt to an unused vector
X *   rupt:		called for an unexpected interrupt (async)
X *   trap:		called for an unexpected trap (synchronous)
X *   panic:		abort MINIX due to a fatal error
X */
X
X#include "kernel.h"
X#include <signal.h>
X#include <minix/config.h>
X#include <minix/callnr.h>
X#include <minix/com.h>
X#include "proc.h"
X
Xstatic void initst();
Xvoid panic();
Xvoid mdiint();
X
X#define SIZES              8	/* sizes array has 8 entries */
X
X/*===========================================================================*
X *                                   main                                    * 
X *===========================================================================*/
XPUBLIC void main()
X{
X/* Start the ball rolling. */
X
X  register struct proc *rp;
X  register int t;
X  register vir_clicks size;
X  register phys_clicks base;
X  reg_t ktsb;
X
X  initst();
X
X  /* Clear the process table.
X   * Set up mappings for proc_addr() and proc_number() macros.
X   */
X  for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
X        rp->p_flags = P_SLOT_FREE;
X        rp->p_nr = t;           /* proc number from ptr */
X        (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
X  }
X 
X  size = sizes[0] + sizes[1];	/* kernel text + data size */
X  base = size;			/* end of kernel */
X
X  ktsb = ((reg_t) t_stack + (ALIGNMENT - 1)) & ~((reg_t) ALIGNMENT - 1);
X  for (t = -NR_TASKS; t < 0; t++) {	/* for all drivers */
X	rp = proc_addr(t);
X	rp->p_flags = 0;
X	ktsb += tasktab[t+NR_TASKS].stksize;
X	rp->p_reg.sp = ktsb;
X	rp->p_splow = rp->p_reg.sp;
X	rp->p_reg.pc = (reg_t) tasktab[t + NR_TASKS].initial_pc;
X	if (!isidlehardware(t)) {
X		lock_ready(rp);	/* IDLE, HARDWARE neveready */
X		rp->p_reg.psw = 0x2200;	/* S-BIT, SPL2 */
X	} else {
X		rp->p_reg.psw = 0x0200;	/* SPL2 */
X	}
X	rp->p_map[T].mem_len  = sizes[0];
X/*	rp->p_map[T].mem_phys = 0; */
X	rp->p_map[D].mem_len  = sizes[1]; 
X	rp->p_map[D].mem_phys = sizes[0];
X/*	rp->p_map[S].mem_len  = 0; */
X	rp->p_map[S].mem_phys = size;
X/*	rp->p_map[T].mem_vir  = rp->p_map[T].mem_phys; */
X	rp->p_map[D].mem_vir  = rp->p_map[D].mem_phys;
X	rp->p_map[S].mem_vir  = rp->p_map[S].mem_phys;
X  }
X
X  rp = proc_addr(HARDWARE);
X  rp->p_map[D].mem_len  = ~0;	/* maximum size */
X  rp->p_map[D].mem_phys = 0;
X  rp->p_map[D].mem_vir  = 0;
X
X  for (t = 0; t <= LOW_USER; t++) {
X	rp = proc_addr(t);
X	rp->p_flags = 0;
X	lock_ready(rp);
X	rp->p_reg.psw = (reg_t)0x0200;	/* no S-BIT, SPL2 */
X	rp->p_reg.pc = (reg_t) ((long)base << CLICK_SHIFT);
X	size = sizes[2*t + 2];
X	rp->p_map[T].mem_len  = size;
X	rp->p_map[T].mem_phys = base;
X	base += size;
X	size = sizes[2*t + 3];
X	rp->p_map[D].mem_len  = size;
X	rp->p_map[D].mem_phys = base;
X	base += size;
X	rp->p_map[S].mem_len  = 0;
X	rp->p_map[S].mem_phys = base;
X	rp->p_map[T].mem_vir  = rp->p_map[T].mem_phys;
X	rp->p_map[D].mem_vir  = rp->p_map[D].mem_phys;
X	rp->p_map[S].mem_vir  = rp->p_map[S].mem_phys;
X  }
X
X  bill_ptr = proc_addr(HARDWARE);	/* it has to point somewhere */
X  lock_pick_proc();
X
X  /* go back to assembly code to start running the current process. */
X}
X
X
X/*===========================================================================*
X *                              none, rupt, trap                             * 
X *===========================================================================*/
XPUBLIC void none()
X{
X  panic("Nonexisting interrupt. Vector =", proc_ptr->p_trap);
X}
X
XPUBLIC void rupt()
X{
X  panic("Unexpected interrupt.  Vector =", proc_ptr->p_trap);
X}
X
X
XPUBLIC void trap()
X{
X  register t;
X  register struct proc *rp;
X  static char vecsig[] = {
X	0, 0, SIGSEGV, SIGBUS, SIGILL, SIGILL, SIGILL, SIGABRT,
X	SIGILL, SIGTRAP, SIGEMT, SIGFPE, SIGSTKFLT
X  };
X
X  rp = proc_ptr;
X  t = rp->p_trap;
X  if (rp->p_reg.psw & 0x2000) panic("trap via vector", t);
X  if (t >= 0 && t < sizeof(vecsig)/sizeof(vecsig[0]) && vecsig[t]) {
X	t = vecsig[t];
X  } else {
X	printf("\nUnexpected trap.  Vector = %d\n", t);
X	printf("This may be due to accidentally including\n");
X	printf("a non-MINIX library routine that is trying to make a system call.\n");
X	t = SIGILL;
X  }
X  if (t != SIGSTKFLT) {	/* DEBUG */
X	printf("sig=%d to pid=%d at pc=%X\n",
X		t, rp->p_pid, rp->p_reg.pc);
X	dump();
X  }
X  cause_sig(proc_number(rp), t);
X}
X
XPUBLIC void checksp()
X{
X  register struct proc *rp;
X  register phys_bytes ad;
X
X  rp = proc_ptr;
X  /* if a user process is is supervisor mode don't check stack */
X  if ((rp->p_nr >= 0) && (rp->p_reg.psw & 0x2000)) return;
X  if (rp->p_reg.sp < rp->p_splow)
X	rp->p_splow = rp->p_reg.sp;
X  if (rp->p_map[S].mem_len == 0)
X	return;
X  ad = (phys_bytes)rp->p_map[S].mem_phys;
X  ad <<= CLICK_SHIFT;
X  if ((phys_bytes)rp->p_reg.sp > ad)
X	return;
X  /*
X   * Stack violation.
X   */
X  ad = (phys_bytes)rp->p_map[D].mem_phys;
X  ad += (phys_bytes)rp->p_map[D].mem_len;
X  ad <<= CLICK_SHIFT;
X  if ((phys_bytes)rp->p_reg.sp < ad + CLICK_SIZE)
X	printf("Stack low (pid=%d,pc=%X,sp=%X,end=%X)\n",
X		rp->p_pid, (long)rp->p_reg.pc,
X		(long)rp->p_reg.sp, (long)ad);
X  rp->p_trap = 12;	/* fake trap causing SIGSTKFLT */
X  trap();
X}
X
X/*===========================================================================*
X *                                   panic                                   * 
X *===========================================================================*/
XPUBLIC void panic(s,n)
Xchar *s;
Xint n; 
X{
X/* The system has run aground of a fatal error.  Terminate execution.
X * If the panic originated in MM or FS, the string will be empty and the
X * file system already syncked.  If the panic originates in the kernel, we are
X * kind of stuck. 
X */
X
X  if (*s != 0) {
X	printf("\nKernel panic: %s",s); 
X	if (n != NO_NUM) printf(" %d", n);
X	printf("\n");
X  }
X  dump();
X  printf("\nPush RESET button\n");
X  for (;;)
X	;
X}
X
X/*
X * Atari ST specific initialization.
X */
X
X#include "staddr.h"
X#include "stacia.h"
X#include "stmfp.h"
X#include "stsound.h"
X#include "stvideo.h"
X
X/*===========================================================================*
X *                                   initst                                   * 
X *===========================================================================*/
XPRIVATE void initst()
X{
X  long ad;
X
X  /*
X   * both 8-bit ports of the sound chip are configured for output
X   */
X  SOUND->sd_selr = YM_MFR;
X  SOUND->sd_wdat = PA_OUT|PB_OUT;
X  /*
X   * init port A (Note: low 3 bits inverted)
X   */
X  SOUND->sd_selr = YM_IOA;
X  SOUND->sd_wdat = SOUND->sd_rdat | PA_PSTROBE;
X  /*
X   * initialize MFP
X   */
X  MFP->mf_ierb |= (IB_DINT|IB_AINT|IB_TIMC|IB_PBSY);
X  MFP->mf_imrb |= (IB_DINT|IB_AINT|IB_TIMC|IB_PBSY);
X  MFP->mf_iera |= (IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
X  MFP->mf_imra |= (IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
X  MFP->mf_vr = V_INIT;
X  /*
X   * The following code is needed if TOS is not in ROM.
X   * It is harmless for more modern systems.
X   */
X  ad = *((long *)0x042E);	/* TOS variable 'phystop' */
X  ad -= 0x8000L;		/* size of VIDEO memory */
X  *((long *)0x0436) = ad;	/* TOS variable '_memtop' */
X  VIDEO->vd_ramm = (char)(ad >> 8);
X  VIDEO->vd_ramh = (char)(ad >> 16);
X}
X
X/*===========================================================================*
X *				aciaint					     *
X *===========================================================================*/
XPUBLIC void aciaint()
X{
X  if (KBD->ac_cs & A_IRQ)
X	kbdint();
X  if (MDI->ac_cs & A_IRQ)
X	mdiint();
X}
X
X/*===========================================================================*
X *				temporary stuff				     *
X *===========================================================================*/
X
XPUBLIC void fake_int(s, t)
Xchar *s;
Xint t;
X{
X  if (t != 0x03)
X    printf("Fake interrupt handler for %s. trap = %02x\n", s, t);
X}
X
XPUBLIC void timint(t)
Xint t;
X{
X  fake_int("timint", t);
X}
X
XPUBLIC void mdiint(t)
Xint t;
X{
X	int code;
X	int i;
X
X	for (i = 0; i < 200; i++) 
X		if (MDI->ac_cs & A_IRQ)
X		{
X			code = MDI -> ac_da;
X			i = 0;	/* re-start time out */
X		}
X}
X
XPUBLIC void iob(t)
Xint t;
X{
X  fake_int("iob", t);
X}
X
X#if (NR_DRIVES == 0)
XPUBLIC void fake_task(s)
Xchar *s;
X{
X  message m;
X
X  /* printf("%s alive\n", s); */
X  for (;;) {
X	receive(ANY, &m);
X	printf("%s received %d from %d\n", s, m.m_type, m.m_source);
X  }
X}
X
XPUBLIC void winchester_task()
X{
X  fake_task("winchester_task");
X}
X#endif
X
XPUBLIC void idle_task()
X{
X#if 0
X    /* the following code is useful to determine stack sizes */
X    static int beenhere = 0;
X    int t;
X    reg_t ktsb;
X    register struct proc *rp;
X
X    if (!beenhere)
X    {
X	beenhere = 1;
X  	ktsb = ((reg_t) t_stack + (ALIGNMENT - 1)) & ~((reg_t) ALIGNMENT - 1);
X	for (t = 0; t < NR_TASKS; t++)
X	{
X	    ktsb += tasktab[t].stksize;
X	    printf("task %s, stack start: %lx\n", tasktab[t].name, ktsb);
X	}
X	for (t = 0; t <= LOW_USER; t++) {
X	    rp = proc_addr(t);
X  	    if (rp->p_splow == 0)
X		rp->p_splow = rp->p_reg.sp;
X	}
X    }
X#endif
X    while (1);
X}
X#endif
SHAR_EOF
sed 's/^X//' << \SHAR_EOF > kernel/stmpx.s
X#include <minix/config.h>
X#include "const.h"
X#if (CHIP == M68000)
X
X!
X! Only the registers that are considered scratch by the compiler used
X! to compile the kernel are saved. Other registers are saved by the
X! prolog generated by the kernel compiler.
X!
X#ifdef ALCYON
X#define FREEREGS d0-d2/a0-a2
X#endif
X#ifdef ACK
X#define FREEREGS d0-d2/a0-a1
X#endif
X
X#ifdef ACK
X! section definition
X	.sect	.text
X	.sect	.rom
X	.sect	.data
X	.sect	.bss
X#endif
X
X!
X! public labels
X!
X	.define	_lock
X	.define	_unlock
X	.define	_restore
X	.define	_reboot
X	.define	_sizes
X#ifdef ACK
X	.define	.trpim
X	.define	.trppc
X#endif
X
X!
X! external references
X!
X	.extern	_clock_handler
X	.extern	_held_head
X	.extern _k_reenter
X	.extern	_proc_ptr
X	.extern	_rdy_head
X	.extern	_lock_pick_proc
X	.extern	_main
X	.extern	_none
X	.extern	_rupt
X	.extern	_trap
X	.extern	_timint
X	.extern	_dmaint
X	.extern	_siaint
X	.extern	_aciaint
X	.extern	_piaint
X	.extern	_iob
X	.extern	_sys_call
X!	.extern	_end
X!	.extern	_edata
X
X!
X! offsets into a proc table entry
X!
Xsava6	= 56
Xsavsp	= 60
Xsavpc	= 64
Xsavsr	= 68
Xsavtt	= 77
X
X	.sect	.text
X!
X! Trap vectors
X!
X.data2	0,	0,	0,	start,	0x0200,	err,	0x0300,	err
X.data2	0x0400,	trp,	0x0500,	trp,	0x0600,	trp,	0x0700,	trp
X.data2	0x0800,	trp,	0x0900,	trc,	0x0A00,	trp,	0x0B00,	trp
X.data2	0x0C00,	trp,	0x0D00,	trp,	0x0E00,	trp,	0x0F00,	trp
X.data2	0x1000,	non,	0x1100,	non,	0x1200,	non,	0x1300,	non
X.data2	0x1400,	non,	0x1500,	non,	0x1600,	non,	0,	conf
X.data2	0x1800,	int,	0x1900,	int,	0,	hbl,	0x1B00,	int
X.data2	0,	vbl,	0x1D00,	int,	0x1E00,	int,	0x1F00,	int
X.data2	0,	sys,	0x2100,	trp,	0x2200,	trp,	0x2300,	trp
X.data2	0x2400,	trp,	0x2500,	trp,	0x2600,	trp,	0x2700,	trp
X.data2	0x2800,	trp,	0x2900,	trp,	0x2A00,	trp,	0x2B00,	trp
X.data2	0x2C00,	trp,	0x2D00,	trp,	0x2E00,	trp,	0x2F00,	trp
X.data2	0x3000,	non,	0x3100,	non,	0x3200,	non,	0x3300,	non
X.data2	0x3400,	non,	0x3500,	non,	0x3600,	non,	0x3700,	non
X.data2	0x3800,	non,	0x3900,	non,	0x3A00,	non,	0x3B00,	non
X.data2	0x3C00,	non,	0x3D00,	non,	0x3E00,	non,	0x3F00,	non
X.data2	0x0000,	pia,	0x0100,	iob,	0x0200,	iob,	0x0300,	iob
X.data2	0x0300,	tim,	0x0200,	clk,	0,	acia,	0,	dma
X.data2	0x0100,	tim,	0x0300,	sia,	0x0200,	sia,	0x0100,	sia
X.data2	0x0000,	sia,	0x0000,	tim,	0x0600,	iob,	0x0700,	iob
X.data2	0x5000,	non,	0x5100,	non,	0x5200,	non,	0x5300,	non
X.data2	0x5400,	non,	0x5500,	non,	0x5600,	non,	0x5700,	non
X.data2	0x5800,	non,	0x5900,	non,	0x5A00,	non,	0x5B00,	non
X.data2	0x5C00,	non,	0x5D00,	non,	0x5E00,	non,	0x5F00,	non
X.data2	0x6000,	non,	0x6100,	non,	0x6200,	non,	0x6300,	non
X.data2	0x6400,	non,	0x6500,	non,	0x6600,	non,	0x6700,	non
X.data2	0x6800,	non,	0x6900,	non,	0x6A00,	non,	0x6B00,	non
X.data2	0x6C00,	non,	0x6D00,	non,	0x6E00,	non,	0x6F00,	non
X.data2	0x7000,	non,	0x7100,	non,	0x7200,	non,	0x7300,	non
X.data2	0x7400,	non,	0x7500,	non,	0x7600,	non,	0x7700,	non
X.data2	0x7800,	non,	0x7900,	non,	0x7A00,	non,	0x7B00,	non
X.data2	0x7C00,	non,	0x7D00,	non,	0x7E00,	non,	0x7F00,	non
X.data2	0x8000,	non,	0x8100,	non,	0x8200,	non,	0x8300,	non
X.data2	0x8400,	non,	0x8500,	non,	0x8600,	non,	0x8700,	non
X.data2	0x8800,	non,	0x8900,	non,	0x8A00,	non,	0x8B00,	non
X.data2	0x8C00,	non,	0x8D00,	non,	0x8E00,	non,	0x8F00,	non
X.data2	0x9000,	non,	0x9100,	non,	0x9200,	non,	0x9300,	non
X.data2	0x9400,	non,	0x9500,	non,	0x9600,	non,	0x9700,	non
X.data2	0x9800,	non,	0x9900,	non,	0x9A00,	non,	0x9B00,	non
X.data2	0x9C00,	non,	0x9D00,	non,	0x9E00,	non,	0x9F00,	non
X.data2	0xA000,	non,	0xA100,	non,	0xA200,	non,	0xA300,	non
X.data2	0xA400,	non,	0xA500,	non,	0xA600,	non,	0xA700,	non
X.data2	0xA800,	non,	0xA900,	non,	0xAA00,	non,	0xAB00,	non
X.data2	0xAC00,	non,	0xAD00,	non,	0xAE00,	non,	0xAF00,	non
X.data2	0xB000,	non,	0xB100,	non,	0xB200,	non,	0xB300,	non
X.data2	0xB400,	non,	0xB500,	non,	0xB600,	non,	0xB700,	non
X.data2	0xB800,	non,	0xB900,	non,	0xBA00,	non,	0xBB00,	non
X.data2	0xBC00,	non,	0xBD00,	non,	0xBE00,	non,	0xBF00,	non
X.data2	0xC000,	non,	0xC100,	non,	0xC200,	non,	0xC300,	non
X.data2	0xC400,	non,	0xC500,	non,	0xC600,	non,	0xC700,	non
X.data2	0xC800,	non,	0xC900,	non,	0xCA00,	non,	0xCB00,	non
X.data2	0xCC00,	non,	0xCD00,	non,	0xCE00,	non,	0xCF00,	non
X.data2	0xD000,	non,	0xD100,	non,	0xD200,	non,	0xD300,	non
X.data2	0xD400,	non,	0xD500,	non,	0xD600,	non,	0xD700,	non
X.data2	0xD800,	non,	0xD900,	non,	0xDA00,	non,	0xDB00,	non
X.data2	0xDC00,	non,	0xDD00,	non,	0xDE00,	non,	0xDF00,	non
X.data2	0xE000,	non,	0xE100,	non,	0xE200,	non,	0xE300,	non
X.data2	0xE400,	non,	0xE500,	non,	0xE600,	non,	0xE700,	non
X.data2	0xE800,	non,	0xE900,	non,	0xEA00,	non,	0xEB00,	non
X.data2	0xEC00,	non,	0xED00,	non,	0xEE00,	non,	0xEF00,	non
X.data2	0xF000,	non,	0xF100,	non,	0xF200,	non,	0xF300,	non
X.data2	0xF400,	non,	0xF500,	non,	0xF600,	non,	0xF700,	non
X.data2	0xF800,	non,	0xF900,	non,	0xFA00,	non,	0xFB00,	non
X.data2	0xFC00,	non,	0xFD00,	non,	0xFE00,	non,	0xFF00,	non
X!
X! gap to allow ramdisk to survive
X!
X	.space	0x0200
X!
X! startup code, just after interrupt vectors
X! clear bss (uninitialized data) section
X! call _main and do process switch when it returns
X!
Xstart:
X!	reset
X	move.w	#0x2700,sr
X	move.l  #k_stktop,sp	
X!	move.l	#_end,d0
X!	move.l	#_edata,a0
X!	bra	L2
X!L1:
X!	move.w	#0,(a0)+
X!L2:
X!	cmp.l	d0,a0
X!	bcs	L1
X	jsr	_main
X	bra	restart
X
X!
X! The vector handlers for synchronous traps. save full context.
X!
Xerr:
X	add.l	#8,sp		! remove extra context
Xtrp:
X	bsr	save
X	jsr	_trap
X	bra	restart
Xtrc:
X	btst	#5,(sp)		! tracing through trap?
X	beq	trp		! No, do normal trace processing
X	rte			! don't trace; execute system call
Xint:
X	bsr	save
X	jsr	_rupt
X	bra	restart
Xnon:
X	bsr	save
X	jsr	_none
X	bra	restart
Xsys:
X	bsr	save			! d0, d1 and a0 not modified
X	move.l	a0,-(sp)		! m_ptr
X	move.w	d1,-(sp)		! src_dest
X	move.w	d0,-(sp)		! SEND/RECEIVE/BOTH
X	move.l	_proc_ptr,a6		! needed to store return value
X				! warning: _sys_call may change _proc_ptr
X	jsr	_sys_call		! sys_call(func,src_dest,m_ptr)
X	move.l  d0,(a6)
X	add.l	#8,sp
X	bra	restart
X!
X! The vector handlers for asynchronous traps. context saved only if necessary.
X!
Xiob:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_iob,a0
X	bsr	async
Xtim:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_timint,a0
X	bsr	async
Xclk:
X	! since the clock cannot be programmed to interrupt at HZ frequency
X	! we'll have to do a divide-by-four in software.
X	sub.w	#1,clkcnt
X	beq	L2a
X	rte
XL2a:
X	move.w	#4,clkcnt
X	movem.l	FREEREGS,-(sp)
X	move.l	#_clock_handler,a0
X	bsr	async
Xdma:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_dmaint,a0
X	bsr	async
Xacia:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_aciaint,a0
X	bsr	async
Xsia:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_siaint,a0
X	bsr	async
Xpia:
X	movem.l	FREEREGS,-(sp)
X	move.l	#_piaint,a0
X	bsr	async
X!
X! The vector handlers that do not affect task switching
X!
Xvbl:
X	! currently still enabled, but ignored
X	! possibly later something like
X	!	movem.l	FREEREGS,-(sp)
X	!	move.l	#_vbl,a0
X	!	bsr	async
X	rte
Xhbl:
X	! must be avoided because it comes so frequent
X	! execute spl2()
X	or.w	#0x200,sr
X	rte
X!
X! Asynchronous Trap
X!
Xasync:
X	clr.w	d0			! extract traptype from saved pc
X	move.b	(sp)+,d0		! sp incremented by 2
X	move.w	d0,(sp)			! push traptype as argument
X	add.b	#1,_k_reenter		! from -1 if not reentering
X	jsr	(a0)			! call service routine
X	tst.w	(sp)+			! pop traptype
X	move.w	#0x2700,sr
X	sub.b	#1,_k_reenter
X	movem.l	(sp)+,FREEREGS
X	btst	#5,(sp)			! previously in kernel mode?
X				! (interrupted a task or another interrupt)
X	bne	L3			! yes: branch and return from interrupt
X	cmp.l	#0,_rdy_head+TASK_Q	! any task just readied?
X	bne	L4			! yes: branch and do task switch
XL3:
X	rte
XL4:
X	bsr	save
X	jsr	_lock_pick_proc
X	bra	restart
X!
X! Perform task switch by save and restart
X!
Xsave:
X	move.w	#0x2700,sr					! ?
X	move.l	a6,-(sp)
X	move.l	_proc_ptr,a6
X	movem.l	d0-d7/a0-a5,(a6)
X	move.l	(sp)+,sava6(a6)		! a6
X	lea	10(sp),a1
X	btst	#5,4(sp)		! test old S-bit
X	bne	L5			! jump if S-bit on
X	move.l	usp,a1
XL5:	move.l	a1,savsp(a6)		! old sp: usp or ksp
X	move.b	(sp),savtt(a6)		! trap type
X	clr.b	(sp)			! cleanup
X	move.l	(sp)+,a1		! return address
X	move.w	(sp)+,savsr(a6)		! sr
X	move.l	(sp)+,savpc(a6)		! pc
X	add.b	#1,_k_reenter		! from -1 if not reentering
X	move.l  #k_stktop,sp	
X	jmp	(a1)
X
Xrestart:
X! Flush any held-up interrupts.
X! This reenables interrupts, so the current interrupt handler may reenter.
X! This doesn't matter, because the current handler is about to exit and no
X! other handlers can reenter since flushing is only done when k_reenter == 0.
X
X	move.w	#0x2700,sr
X	tst.b	_k_reenter
X	bne	over_call_unhold
X	cmp.l	#0,_held_head
X	beq	over_call_unhold
X	jsr	_unhold
Xover_call_unhold:
X	sub.b	#1,_k_reenter
X	jsr	_checksp
X	move.l	_proc_ptr,a6
X	move.l	savsp(a6),a0		! old sp: usp or ksp
X	btst	#5,savsr(a6)		! test old S-bit
X	bne	L6			! jump if S-bit on
X	move.l	a0,usp
X	bra	L7
XL6:	move.l	a0,sp
XL7:	move.l	savpc(a6),-(sp)		! pc
X	move.w	savsr(a6),-(sp)		! sr
X	movem.l	(a6),d0-d7/a0-a6
X	rte
X
X_lock:
X	move.w	sr,d0
X	move.w	#0x2700,sr
X	rts
X_restore:
X	move.w	4(sp),sr
X	rts
X_unlock:
X	move.w	#0x2200,sr		! spl2() to block HBL interrupt
X	rts
X_reboot:
X	move.l	4,a0
X	jmp	(a0)
X
X	.sect	.data
X
X_sizes:
X	.data2	0x526F,0,0,0,0,0,0,0
Xconf:
X	.extern	_proc
X	.data4	_proc
X	.extern	_keynorm
X	.data4	_keynorm
X	.extern	_keyshft
X	.data4	_keyshft
X	.extern	_keycaps
X	.data4	_keycaps
X	.extern	_font8
X	.data4	_font8
X	.extern	_font16
X	.data4	_font16
X	.data4	0
X
Xclkcnt: .data2  4
X
X	.space K_STACK_BYTES
Xk_stktop:
X
X#ifdef ACK
X	.sect	.text
X	.extern	_write
X	.extern	EXIT
X_write:
XEXIT:
X	bra	EXIT
X
X	.sect	.text
X.trpim:	.data2	0
X.trppc:	.data4	0
X#endif ACK
X
X#endif
SHAR_EOF
#	End of shell archive
exit 0
Frans Meulenbroeks        (meulenbr@cst.philips.nl)
	Centre for Software Technology
	( or try: ...!mcsun!phigate!prle!cst!meulenbr)