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)