Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 1 - By Bruce Evans
Message-ID: <5263@ditmela.oz>
Date: 18 May 89 01:19:25 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1185

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 10)."
# Contents:  MANIFEST README INSTALL crc-after crc-before crc-dist
#   crc-misc commandsdif fsdif hdif kerneldif libdif mmdif toolsdif
#   commandsdif/CHANGES fsdif/CHANGES hdif/CHANGES libdif/CHANGES
#   mmdif/CHANGES toolsdif/CHANGES commandsdif/readclock.c.cd
#   fsdif/at_makefile.cd fsdif/device.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:33:40 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(2471 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X README                     1	
X INSTALL                    1	
X crc-after                  1	
X crc-before                 1	
X crc-dist                   1	
X crc-misc                   1	
X commandsdif                1	
X fsdif                      1	
X hdif                       1	
X kerneldif                  1	
X libdif                     1	
X mmdif                      1	
X toolsdif                   1	
X commandsdif/CHANGES        1	
X fsdif/CHANGES              1	
X hdif/CHANGES               1	
X kerneldif/CHANGES          2	
X libdif/CHANGES             1	
X mmdif/CHANGES              1	
X toolsdif/CHANGES           1	
X commandsdif/readclock.c.cd  1	
X fsdif/at_makefile.cd       1	
X fsdif/cache.c.cdif         2	
X fsdif/device.c.cdif        1	
X fsdif/inode.c.cdif         2	
X fsdif/main.c.cdif          2	
X fsdif/misc.c.cdif          2	
X fsdif/pipe.c.cdif          2	
X fsdif/super.c.cdif         2	
X fsdif/table.c.cdif         2	
X fsdif/utility.c.cdif       2	
X hdif/boot.h.cdif           2	
X hdif/com.h.cdif            2	
X hdif/const.h.cdif          2	
X kerneldif/Bconsole.c.cdi   2	
X kerneldif/Brs232.c.cdif    2	
X kerneldif/Btty.c.cdif      3	
X kerneldif/at_wini.c.cdif   3	
X kerneldif/axmakefile.cdi   3	
X kerneldif/clock.c.cdif     3	
X kerneldif/console.c.cdif   3	
X kerneldif/const.h.cdif     3	
X kerneldif/dmp.c.cdif       4	
X kerneldif/exception.c.cd   4	
X kerneldif/floppy.c.cdif    4	
X kerneldif/glo.h.cdif       4	
X kerneldif/i8259.c.cdif     4	
X kerneldif/klib286.x.cdif   4	
X kerneldif/klib88.x.cdif    5	
X kerneldif/main.c.cdif      4	
X kerneldif/memory.c.cdif    6	
X kerneldif/misc.c.cdif      6	
X kerneldif/mpx286.x.cdif    6	
X kerneldif/mpx88.x.cdif     6	
X kerneldif/printer.c.cdif   6	
X kerneldif/proc.c.cdif      7	
X kerneldif/proc.h.cdif      7	
X kerneldif/protect.c.cdif   8	
X kerneldif/protect.h.cdif   7	
X kerneldif/rs2.x.cdif       8	
X kerneldif/rs232.c.cdif     8	
X kerneldif/sconst.h.cdif    8	
X kerneldif/sglo.h.cdif      8	
X kerneldif/system.c.cdif    9	
X kerneldif/table.c.cdif     6	
X kerneldif/tty.c.cdif       3	
X kerneldif/type.h.cdif      7	
X kerneldif/xt_wini.c.cdif   8	
X libdif/head.s.cdif         8	
X mmdif/alloc.c.cdif         9	
X mmdif/main.c.cdif          9	
X mmdif/signal.c.cdif        4	
X toolsdif/build.c.cdif     10	
X toolsdif/fsck.c.cdif       9	
X toolsdif/fsck1.s.cdif      8	
END_OF_FILE
if test 2471 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(9669 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XHere are patches to Minix 1.3d to provide:
X
X	o use of 286 protected mode on 286's and 386's.
X	o overhaul of interrupt handling to reduce latency by a huge factor.
X	o changes to FS and boot programs to allow the root device and RAM
X	  disk size to be specified at boot time.
X	o several minor bug fixes.
X
XThe 286 system binaries remain capable of running on 8088 systems, and can
Xbe limited at boot time to 8088 mode on 286's to provide full backward
Xcompatibility. Most testing was done on a 386-AT, some on a real PC, and
Xa little on a clone-AT and a Toshiba 1100 (8088 portable). I tried to avoid
Xbreaking nonstandard configurations but didn't touch Amoeba (it can no
Xlonger work) and may have messed up the PS/2 Model 30.
X
XProtected mode.
X---------------
X
XThe protection is of of system processes from wild user processes.
XProtected mode also provides a 16MB address space, limited mainly by
Xavailable RAM and by the small model to 64K code + 64K data per process.
XI am usually greeted by a startup message like:
X
XMemory size = 1024K     MINIX = 127K     RAM disk =   0K     Available = 897K
X
XProtected mode has some drawbacks. Interrupt handling is 5 to 10% slower
Xbecause loading segment registers takes a long time. It is imprudent to
Xallow users easy access to the i/o ports and another project to allow access
Xto memory outside the data segment. Badly-behaved programs try to do these
Xthings and will cause an exception in protected mode. Other pitfalls are
Xwriting to the code segment, and assuming code segment == data segment
Xbecause the program is common I&D. It is possible for a program to almost
Xlock up the system if it ignores SIGSEGV and then causes one (many
Xexceptions resume at the faulty PC since the signal handlers are too
Xsimple). CTRL-F9 is needed to break out of that. Fortunately most Minix
Xprograms are well-behaved.
X
XThis kernel provides /dev/port to go with /dev/mem so ports can be accessed
X(slowly) by suitably privileged users. Only readclock uses this now. Things
Xlike EGA graphics will require immediate access to both ports and screen
Xmemory. It is easy to provide the memory access by expanding the per-process
Xlocal descriptor table, but not clear how to interface the capability. Ports
Xare more difficult since the 286 allows access to all or none, depending on
Xthe IOPL bits in the PSW. The 386 allows a more flexible permissions bitmap.
XStill, port-mapped i/o is awful for software.
X
XMy 386 protected mode code is not included here since it offers few
Xcapabilities beyond what the 286 can do, so I'm reserving it for a proper
X32 bit 386 version. The changes for it are simple but bulky. All the
Xassembler code uses 386 instructions where appropriate. This is not
Xessential (below 16M) but is cleaner - until you ask asld to assemble it.
XThe interrupt handlers have to save and restore 32 bit registers - this
Xinvolves little more than putting 'e' in front of register names and 'd'
Xafter some instructions. The process table structure has to be larger to
Xhold the larger registers. "protect.c" needs a few more lines to initialize
Xthe top 2 bytes in segment descriptors and to build 32 bit TSS's.
XEverywhere that a saved register is accessed, the code needs to test the
Xprocessor variable to decide whether to use an r16 (8088-286) register or
Xr32 (386) register. It is practical to store 8088 r16's in the r32's (for
Xan 8088/386 kernel like I started with) but not 80286 r16's since that
Xrequires too much rebuilding of the stack frame. And all this is worthless
Xwithout a 386 compiler and a hacked library to interface to the 16 bit
Xkernel.
X
XInterrupt handling.
X-------------------
X
XThe 1.3 kernel leaves interrupts off while it does context-switching and
Xhardware interrupt handling. This takes a few hundred instructions, well
Xover 1ms on a 5MHz 8088, and sometimes an iteration causes an even longer
Xdelay. My TTY driver with this kernel will go no faster than 2400 baud,
Xwhich suggests that the normal worst case latency is about 4ms. The 1.3
XTTY driver has internal inefficiencies which makes it another 4 to 8
Xtimes slower.
X
XThis kernel improves the interrupt latency by a factor of about 12 in two
Xsteps. The first step is to run the main part of the context-switcher
X(sys_call()) with interrupts enabled, and rewrite the interrupt handler
Xto task interface (interrupt()) to be more efficient. This, together with
Xother small changes to proc.c, mainly using pointers instead of arrays and
Xarrays instead of pointer arithmetic, gives about a factor of 4 improvement.
X
XThe second step is to enable interrupts while most interrupt handlers are
Xrunning. Ideally, only save() and restart() and some *small* critical
Xregions should have interrupts disabled. In practice, fast asynchronous
Xinput devices like RS232 need interrupts disabled throughout their
Xinterrupt handler.
X
XSeveral methods are used to prevent reentry to critical regions without
Xlocking everything. The variable 'k_reenter' is the most important. It
Xcounts reentries into the kernel (context-switching and interrupt handling).
XInterrupt() may not reenter unless k_reenter is 0 (when there is exactly
Xone interrupt handler in the kernel, and no sys_call()). Calls from nested
Xhandlers are delayed until the first handler finishes, using a little queue.
XThis is cheap because now only task numbers have to be queued. Calls to
Xcontext-switching functions are also critical. The main one, sys_call(),
Xneeds no special treatment since interrupt handlers may not call it.
XComplications are caused by calls from tasks, e.g. sched(), when k_reenter
Xis -1. These are protected by the flag 'switching', since k_reenter is
Xused to tell when to switch stacks as well as for locking, so cannot be
Xadjusted. Curiously, interrupt() may be called when k_reenter is -1 (e.g.
Xfor TTY_O_DONE), but this causes no trouble.
X
XHardware locking is still used for individual interrupt lines to ensure
Xthat no interrupt handler is ever reentered. This bounds the amount of
Xkernel stack required, and eliminates most competition for shared variables.
XSee mpx88.x and klib88.x. I think the low level is now correct for level-
Xsensitive interrupts on PS/2's, but haven't tested it. Access to shared
Xvariables is now very tricky. The clock handler locks everything for short
Xregions. The printer driver uses a test-and-set on its hardware mask bit.
XMy TTY driver uses a test-and-set on a normal variable - see tty_wakeup().
XThis is beginning to look like another operating system beneath the message
Xpassing.
X
XSelect root device etc. at boot time.
X-------------------------------------
X
XThe boot program (standalone fsck) has several more options on the menu, to
Xselect the system configuration:
X
X	o root device
X	o RAM image device
X	o RAM disk size
X	o processor limit
X
XNot all combinations are valid. The keyboard type was already specified by
Xthe scan code. The processor limit is the way of handicapping 286 and 386
Xprocessors so they run in 8088 mode. Fsck fills in a structure with the
Xoptions and passes it to kernel and FS.
X
XThis lets me test lots of variants of the system without recompiling. In
Xparticular I can keep my setup with the hard disk as root when testing
Xthe version to be posted!
X
XThe changes in FS mainly involve replacing BOOT_DEV and ROOT_DEV by
Xvariables and eliminating unwarranted messages about the RAM disk being
Xroot. The "h/boot.h" file is kept separate and so needs including all over
Xbecause it is needed by the bootstrap program (fsck.c here). Supporting
Xcode is in fsck.c, fsck1.s, mpx88.x, com.h and system.c. Adding a system
Xcall to support copying the parameters from kernel to FS was a lot of
Xwork but FS can't sensibly call sys_copy() since it doesn't know where
Xthey are.
X
X
XReorganized assembler files.
X----------------------------
X
XIt was too hard to maintain constants across several files without being 
Xable to include header files, and asld lacked the ability to handle 286 code
Xeven via macros. So all the '.s' files are renamed '.x' files and passed
Xthrough the C preprocessor (automatically with make). Most of the constants
Xdefined in the C header files become available in the assembler code. One
Xproblem is that asld wants "[]" for parentheses, so many derived constants
Xhave to be defined as if they were fundamental.
X
XTTY.
X----
X
XThe TTY driver I posted in January should have been a prerequisite to these
Xchanges, but I forgot to say so at the time. I didn't want to post it all
Xagain since this is already too long, so made minimal changes to get the 1.3
Xdriver working. Diffs for both versions are included. I don't trust the
X1.3 version but used it to upload this posting at 2400 baud with no trouble.
X
XMy version now works at 19.2K baud on a 4.77MHz 8088 (1700 chars/sec
Xthroughput) and on 2 lines at 115.2K baud on a 20MHz 386 (2 x 8000 chars/sec
Xthroughput). The 1.3 version works at 2400 baud on the PC and 2 x 9600 baud
Xon the 386. Running RS232 at a high speed is a good test of interrupt
Xhandling. I ran the dual lines test by logging into tty2 using term on tty1.
XThis requires 2 serial ports but no fast external devices.
X
XDebugger.
X---------
X
XThe debugger I posted last December needs upgrading to work with this kernel.
XEven in real mode, it needs small changes. I have a version for protected
Xmode, but it only runs on 386's since it needs to switch to real mode to run.
XI consider a debugger essential for serious work on the system, but mine no
Xlonger compiles with the usual tools:
X
XAsld problems.
X--------------
X
XAsld may be close to running out of space when linking the kernel. It failed
Xungracefully when trying to link the kernel + debugger. Yet a core dump
Xshowed it had 10K of zeros between heap and stack.
END_OF_FILE
if test 9669 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(4428 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
XInstallation guide for protected mode Minix.
X--------------------------------------------
X
X1. Unpack the shars. It is best to work in a fresh directory. The shell will
Xcreate files README, INSTALL, MANIFEST, crc-dist, crc-before, crc-after and
Xcrc-misc, and subdirectories commandsdif, fsdif, hdif, kerneldif, libdif,
Xmmdif and toolsdif. You will need about 400K more space. The diffs include
Xseveral new files in cdiff format so patch can handle them.
X
X2. Examine crc-before for the list of prerequisite files. This is just the
Xheart of what I think is 1.3d (from the "1.3 - final wrapup" posting last
XOctober). If your files are different, the new kernel may not work. If you
Xhave the right files but usually use a patched version, I suggest going back
Xto 1.3d to start with (except the 1.4a floppy.c and my patches for TTY are
Xsupported here). In the kernel directory, there are so many changes that
Xsomething is sure to go wrong if you start from the wrong base. The other
Xpatches here won't cause so much trouble, but beware of clashes with ones
XI've already posted and the one to FS to put the root file system on the
Xhard disk.
X
X3. Make full working copies of the fs, h, kernel, mm and tools directories
X(or back up everything). Also make directories and files commands/readclock.c
Xand lib/IBM_PC/head.s. This requires about 800K more space.
X
X4. If you have the 1.4a floppy.c, use it. The floppy diff is in fact relative
Xto this version, but the 1.3d version works too (but causes warnings from
Xpatch). If you want to use my TTY (posted in January), move tty.c.cdif,
Xrs232.c.cdif and console.c.cdif in kerneldif somewhere out of the diff list,
Xand rename Btty.c.cdif, Brs232.c.cdif and Bconsole.c.cdif to them, and get
Xthe files tty.c, rs232.c, console.c and tty.h (only) from my posting. Use
Xcrc-misc to check the files are correct.
X
X5. Apply the patches. The diffs were made from the minix directory (the one
Xabove kernel, mm etc.) so patch can do everything in one step with a
Xcommand like:
X
X	(cd dir-used-to-unpack; cat *dif/[a-z]*) | \
X	(cd dir-used-for-source-dirs; patch -p -N 2>&1 | tee patch.out)
X
XThis requires about 1100K more space (patch will make 550K files in /tmp).
XYou may have to do the patches a few at a time if space is tight, or one at
Xa time in case of trouble.
X
X6. Check the new files against crc-after.
X
X7. Move the original copies of the patched files to backup directories or
Xdelete them. Do the same with the following kernel files which have become
Xobsolete:
X
X	at_makefile, klib88.s, mpx88.s, xt_makefile.
X
XThe separate copy of wini.c is also obsolete. In the old lib/IBM_PC (not
Xtouched by the patches), getutil.s and portio.s are obsolete. These can be
Xleft for now, but it is best to take them out of libc.a since they will give
Xcore dumps in protected mode.
X
X8. Link or copy all the at_makefile's or xt_makefile's to makefile's. In
Xthe fs directory, there is a new at_makefile but no new xt_makefile - patch
Xxt_makefile if you need to use it. In the kernel directory, there is now only
Xaxmakefile, for both. It will compile for XT's but may need editing to run
Xon XT's. If you are using my TTY, edit the kernel makefile to select it.
XThere are many options in axmakefile which are of no use to anyone but me,
Xbut you may want to reverse the LINEWRAP and STUPID_WINI selections to
Xsomething saner, and maybe try SPARE_VIDEO. The whole kernel should really
Xdepend on axmakefile to force recompiling it all when a define is changed.
X
X9. Re-make tools/build and tools/fsck and then an image with your old
Xkernel+mm+fs+init and check that the image still works. The new options on
Xthe fsck menu should do nothing.
X
X10. Link or copy the new lib/IBM_PC/head.s to /usr/lib/head.s.
X
X11. Re-make kernel, mm, fs, init as usual. The old ones must not be mixed,
Xsince kernel, mm and fs use a new CLICK_SIZE and a couple more system calls,
Xand kernel wants init to have a larger initial stack.
X
X12. Make a new image.
X
X13. Make the new readclock and then the port device for readclock to use:
X
X	su root
X	mknod /dev/port c 1 4
X
Xand fix the memory device for it:
X
X	rm /dev/mem
X	mknod /dev/mem c 1 1
X
XThese must go on the (old) root DISK.
X
X14. Boot the new image. There are several new installation possibilities
Xprovided from the new options on the boot menu. I suggest changing the
Xdefault boot parameters in fsck.c if they don't suit you. I use /dev/hd2
Xfor the root device and 0 for the RAM disk size.
END_OF_FILE
if test 4428 -ne `wc -c <'INSTALL'`; then
    echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
# end of 'INSTALL'
fi
if test -f 'crc-after' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crc-after'\"
else
echo shar: Extracting \"'crc-after'\" \(2915 characters\)
sed "s/^X//" >'crc-after' <<'END_OF_FILE'
X25125   6397 commands/readclock.c
X62514   4313 fs/at_makefile
X61318   2988 fs/buf.h
X63516  10843 fs/cache.c
X49601   2925 fs/const.h
X32651    273 fs/dev.h
X28661   8604 fs/device.c
X43804    474 fs/file.h
X08379   3225 fs/filedes.c
X03291   1502 fs/fproc.h
X32100   1013 fs/glo.h
X45668   7813 fs/inode.c
X05436   1943 fs/inode.h
X37259   5662 fs/link.c
X20987  16844 fs/main.c
X49598   7693 fs/misc.c
X59037   6257 fs/mount.c
X08819   9226 fs/open.c
X59312   1557 fs/param.h
X44200  10716 fs/path.c
X46842   4266 fs/pc_makefile
X19890   8581 fs/pipe.c
X01700   5864 fs/protect.c
X11848   1440 fs/putc.c
X15755  12205 fs/read.c
X14710   5397 fs/stadir.c
X61743   8935 fs/super.c
X10348   2081 fs/super.h
X52747   4314 fs/table.c
X03667   2620 fs/time.c
X56368    710 fs/type.h
X15923   5419 fs/utility.c
X00551   7367 fs/write.c
X46158   1142 h/boot.h
X45442   1683 h/callnr.h
X10716   7725 h/com.h
X25227   4420 h/const.h
X48562   2191 h/error.h
X03794   1412 h/sgtty.h
X06265   1115 h/signal.h
X51139    861 h/stat.h
X16557   4001 h/type.h
X50110   3188 kernel/at_makefile
X27982  16308 kernel/at_wini.c
X42574   7662 kernel/axmakefile
X22105  11246 kernel/clock.c
X60674  34356 kernel/console.c
X52636   4410 kernel/const.h
X60752   3349 kernel/dmp.c
X08141   2109 kernel/exception.c
X26501  27169 kernel/floppy.c
X00100   1763 kernel/glo.h
X41282   2138 kernel/i8259.c
X12547   7691 kernel/klib286.x
X16069  36914 kernel/klib88.x
X33778  10292 kernel/main.c
X50746   5654 kernel/memory.c
X31337   2467 kernel/misc.c
X45692   6750 kernel/mpx286.x
X01231  15602 kernel/mpx88.x
X65108   3375 kernel/pc_makefile
X25702  10264 kernel/printer.c
X45651  17211 kernel/proc.c
X06198   3783 kernel/proc.h
X26519   9012 kernel/protect.c
X52909   4675 kernel/protect.h
X12176  18813 kernel/ps_wini.c
X05156   5764 kernel/rs2.x
X39870  19682 kernel/rs232.c
X23697   4804 kernel/sconst.h
X13106   4177 kernel/sglo.h
X48093  24928 kernel/system.c
X28634   3838 kernel/table.c
X38180  28073 kernel/tty.c
X34455   7485 kernel/tty.h
X44806   4708 kernel/ttymaps.h
X23087   1815 kernel/type.h
X32712  26756 kernel/xt_wini.c
X24479    880 lib/IBM_PC/head.s
X32432   8523 mm/alloc.c
X49710   1833 mm/at_makefile
X05784   7234 mm/break.c
X43289    744 mm/const.h
X37617  17077 mm/exec.c
X17024   9871 mm/forkexit.c
X34366   1572 mm/getset.c
X06761    799 mm/glo.h
X36536   8885 mm/main.c
X46388   1661 mm/mproc.h
X21684    677 mm/param.h
X39295   1890 mm/pc_makefile
X54292   1487 mm/putc.c
X45715  13879 mm/signal.c
X09215   3143 mm/table.c
X17333    238 mm/type.h
X20567   4181 mm/utility.c
X59520   2249 tools/at_makefile
X13594   8083 tools/bootblok.s
X61341  24303 tools/build.c
X53860   1298 tools/changemem
X36909  48595 tools/fsck.c
X18310   3421 tools/fsck1.s
X39871     44 tools/group
X21308   6082 tools/init.c
X43560    327 tools/message
X52749  25884 tools/mkfs.c
X52059     97 tools/passwd
X59520   2249 tools/pc_makefile
X00735    105 tools/profile
X09800    197 tools/rc
X12541      4 tools/ttys
X10241     22 tools/ttytype
END_OF_FILE
if test 2915 -ne `wc -c <'crc-after'`; then
    echo shar: \"'crc-after'\" unpacked with wrong size!
fi
# end of 'crc-after'
fi
if test -f 'crc-before' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crc-before'\"
else
echo shar: Extracting \"'crc-before'\" \(2574 characters\)
sed "s/^X//" >'crc-before' <<'END_OF_FILE'
X52678   4113 commands/readclock.c
X19878   4197 fs/at_makefile
X61318   2988 fs/buf.h
X31034  10863 fs/cache.c
X49601   2925 fs/const.h
X32651    273 fs/dev.h
X54203   8530 fs/device.c
X43804    474 fs/file.h
X08379   3225 fs/filedes.c
X03291   1502 fs/fproc.h
X32100   1013 fs/glo.h
X62665   7839 fs/inode.c
X05436   1943 fs/inode.h
X37259   5662 fs/link.c
X15515  15303 fs/main.c
X43484   7670 fs/misc.c
X59037   6257 fs/mount.c
X08819   9226 fs/open.c
X59312   1557 fs/param.h
X44200  10716 fs/path.c
X46842   4266 fs/pc_makefile
X08656   8462 fs/pipe.c
X01700   5864 fs/protect.c
X11848   1440 fs/putc.c
X15755  12205 fs/read.c
X14710   5397 fs/stadir.c
X11343   8912 fs/super.c
X10348   2081 fs/super.h
X46563   4312 fs/table.c
X03667   2620 fs/time.c
X56368    710 fs/type.h
X42080   5396 fs/utility.c
X00551   7367 fs/write.c
X45442   1683 h/callnr.h
X55177   7424 h/com.h
X21531   4403 h/const.h
X48562   2191 h/error.h
X03794   1412 h/sgtty.h
X06265   1115 h/signal.h
X51139    861 h/stat.h
X16557   4001 h/type.h
X50110   3188 kernel/at_makefile
X64098  16075 kernel/at_wini.c
X11053   9335 kernel/clock.c
X01201  33549 kernel/console.c
X46559   2880 kernel/const.h
X09961   3543 kernel/dmp.c
X37030  26551 kernel/floppy.c
X39457    881 kernel/glo.h
X29135  26496 kernel/klib88.s
X01335  11156 kernel/main.c
X36060   5296 kernel/memory.c
X09331  13834 kernel/mpx88.s
X65108   3375 kernel/pc_makefile
X56408   9952 kernel/printer.c
X10507  13753 kernel/proc.c
X21644   2324 kernel/proc.h
X12176  18813 kernel/ps_wini.c
X59321  19053 kernel/rs232.c
X61988  19960 kernel/system.c
X38305   3634 kernel/table.c
X03407  28073 kernel/tty.c
X34455   7485 kernel/tty.h
X44806   4708 kernel/ttymaps.h
X27554    742 kernel/type.h
X14198  26433 kernel/xt_wini.c
X63856    478 lib/IBM_PC/head.s
X59150   7857 mm/alloc.c
X49710   1833 mm/at_makefile
X05784   7234 mm/break.c
X43289    744 mm/const.h
X37617  17077 mm/exec.c
X17024   9871 mm/forkexit.c
X34366   1572 mm/getset.c
X06761    799 mm/glo.h
X41965   7272 mm/main.c
X46388   1661 mm/mproc.h
X21684    677 mm/param.h
X39295   1890 mm/pc_makefile
X54292   1487 mm/putc.c
X55828  13811 mm/signal.c
X09215   3143 mm/table.c
X17333    238 mm/type.h
X20567   4181 mm/utility.c
X59520   2249 tools/at_makefile
X13594   8083 tools/bootblok.s
X02360  19714 tools/build.c
X53860   1298 tools/changemem
X51921  45901 tools/fsck.c
X34431   3158 tools/fsck1.s
X39871     44 tools/group
X21308   6082 tools/init.c
X43560    327 tools/message
X52749  25884 tools/mkfs.c
X52059     97 tools/passwd
X59520   2249 tools/pc_makefile
X00735    105 tools/profile
X09800    197 tools/rc
X12541      4 tools/ttys
X10241     22 tools/ttytype
END_OF_FILE
if test 2574 -ne `wc -c <'crc-before'`; then
    echo shar: \"'crc-before'\" unpacked with wrong size!
fi
# end of 'crc-before'
fi
if test -f 'crc-dist' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crc-dist'\"
else
echo shar: Extracting \"'crc-dist'\" \(2232 characters\)
sed "s/^X//" >'crc-dist' <<'END_OF_FILE'
X39626   4428 INSTALL
X61974   9669 README
X19619   2915 crc-after
X62357   2574 crc-before
X20225    521 crc-misc
X27208    585 commandsdif/CHANGES
X27898   2780 commandsdif/readclock.c.cd
X52949   1602 fsdif/CHANGES
X58458    742 fsdif/at_makefile.cd
X55444    629 fsdif/cache.c.cdif
X33361    296 fsdif/device.c.cdif
X64779    651 fsdif/inode.c.cdif
X09177   7501 fsdif/main.c.cdif
X28991    200 fsdif/misc.c.cdif
X63682    733 fsdif/pipe.c.cdif
X23503    202 fsdif/super.c.cdif
X32449    596 fsdif/table.c.cdif
X52345    206 fsdif/utility.c.cdif
X07989   1334 hdif/CHANGES
X56867   1346 hdif/boot.h.cdif
X11669   1355 hdif/com.h.cdif
X11064   1785 hdif/const.h.cdif
X54703   7608 kerneldif/Bconsole.c.cdi
X10299    314 kerneldif/Brs232.c.cdif
X44727   2878 kerneldif/Btty.c.cdif
X61366  13586 kerneldif/CHANGES
X53869   4503 kerneldif/at_wini.c.cdif
X29962   8507 kerneldif/axmakefile.cdi
X19879  10602 kerneldif/clock.c.cdif
X33096   3676 kerneldif/console.c.cdif
X17774   7031 kerneldif/const.h.cdif
X18063   4759 kerneldif/dmp.c.cdif
X23580   2371 kerneldif/exception.c.cd
X43539   3990 kerneldif/floppy.c.cdif
X32425   2154 kerneldif/glo.h.cdif
X00732   2394 kerneldif/i8259.c.cdif
X36863   8420 kerneldif/klib286.x.cdif
X01389  39670 kerneldif/klib88.x.cdif
X00997  13597 kerneldif/main.c.cdif
X56052   3714 kerneldif/memory.c.cdif
X28868   2738 kerneldif/misc.c.cdif
X01013   7400 kerneldif/mpx286.x.cdif
X35915  16900 kerneldif/mpx88.x.cdif
X41122   6243 kerneldif/printer.c.cdif
X21517  26431 kerneldif/proc.c.cdif
X28250   4435 kerneldif/proc.h.cdif
X59265   9757 kerneldif/protect.c.cdif
X36213   5010 kerneldif/protect.h.cdif
X30637   6495 kerneldif/rs2.x.cdif
X03401   3649 kerneldif/rs232.c.cdif
X31596   5266 kerneldif/sconst.h.cdif
X09445   4801 kerneldif/sglo.h.cdif
X27539  20205 kerneldif/system.c.cdif
X30325   1373 kerneldif/table.c.cdif
X11117    808 kerneldif/tty.c.cdif
X42827   2827 kerneldif/type.h.cdif
X55080   4227 kerneldif/xt_wini.c.cdif
X19725    344 libdif/CHANGES
X18965   1162 libdif/head.s.cdif
X11734   1851 mmdif/CHANGES
X29780   3094 mmdif/alloc.c.cdif
X27845   5879 mmdif/main.c.cdif
X35100    448 mmdif/signal.c.cdif
X26848    524 toolsdif/CHANGES
X16877  16217 toolsdif/build.c.cdif
X33760   5747 toolsdif/fsck.c.cdif
X07957    462 toolsdif/fsck1.s.cdif
END_OF_FILE
if test 2232 -ne `wc -c <'crc-dist'`; then
    echo shar: \"'crc-dist'\" unpacked with wrong size!
fi
# end of 'crc-dist'
fi
if test -f 'crc-misc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crc-misc'\"
else
echo shar: Extracting \"'crc-misc'\" \(521 characters\)
sed "s/^X//" >'crc-misc' <<'END_OF_FILE'
X1.4a floppy.c, before patching
X------------------------------
X02252  28600 kernel/floppy.c
X
X1.4a floppy.c, after patching
X-----------------------------
X26150  29218 kernel/floppy.c
X
XMy tty files, before patching
X-----------------------------
X57278  34367 kernel/console.c
X65263  19504 kernel/rs232.c
X16498  37486 kernel/tty.c
X40473   8522 kernel/tty.h
X
XMy tty files, after patching
X----------------------------
X41029  39407 kernel/console.c
X58421  19572 kernel/rs232.c
X28361  37783 kernel/tty.c
X40473   8522 kernel/tty.h
END_OF_FILE
if test 521 -ne `wc -c <'crc-misc'`; then
    echo shar: \"'crc-misc'\" unpacked with wrong size!
fi
# end of 'crc-misc'
fi
if test ! -d 'commandsdif' ; then
    echo shar: Creating directory \"'commandsdif'\"
    mkdir 'commandsdif'
fi
if test ! -d 'fsdif' ; then
    echo shar: Creating directory \"'fsdif'\"
    mkdir 'fsdif'
fi
if test ! -d 'hdif' ; then
    echo shar: Creating directory \"'hdif'\"
    mkdir 'hdif'
fi
if test ! -d 'kerneldif' ; then
    echo shar: Creating directory \"'kerneldif'\"
    mkdir 'kerneldif'
fi
if test ! -d 'libdif' ; then
    echo shar: Creating directory \"'libdif'\"
    mkdir 'libdif'
fi
if test ! -d 'mmdif' ; then
    echo shar: Creating directory \"'mmdif'\"
    mkdir 'mmdif'
fi
if test ! -d 'toolsdif' ; then
    echo shar: Creating directory \"'toolsdif'\"
    mkdir 'toolsdif'
fi
if test -f 'commandsdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'commandsdif/CHANGES'\"
else
echo shar: Extracting \"'commandsdif/CHANGES'\" \(585 characters\)
sed "s/^X//" >'commandsdif/CHANGES' <<'END_OF_FILE'
Xreadclock.c:
X	o Avoided the direct access to ports and memory.
X	  It is not allowed in protected mode.
X	  The routines here may belong in the library (instead of portio.s)
X	  but are slow and waste file descriptors.
X	  They do everything through /dev/port and /dev/mem.
X	  They are subtly different since they are not guaranteed to succeed,
X	  so an error code must be checked for.
X	  The 640K size in the inode of the version 1.3 /dev/mem is bogus.
X	  It needs to be 1M for the peek in readclock.c, and 16M to be
X	  reasonable on AT's.
X	  Device sizes in inodes don't work very well.
END_OF_FILE
if test 585 -ne `wc -c <'commandsdif/CHANGES'`; then
    echo shar: \"'commandsdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'commandsdif/CHANGES'
fi
if test -f 'fsdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/CHANGES'\"
else
echo shar: Extracting \"'fsdif/CHANGES'\" \(1602 characters\)
sed "s/^X//" >'fsdif/CHANGES' <<'END_OF_FILE'
XGeneral:
X	o The root device, RAM image device and RAM disk size can be changed
X	  at boot time (using the new tools/fsck.c).
X	  The magic numbers are passed in a structure from the bootstrap
X	  program through the kernel to FS.
X	  ../h/boot.h declares this structure and defines some constants.
X	  This should make most of the special ST code unnecessary.
Xcache.c:
X	o Included boot.h and changed message about out of space on device.
Xdevice.c:
X	o Adjusted TTY_SPEED returned by do_ioctl for V1.2 compatibility.
X	  Programs like elle compiled with old libraries sometimes trashed
X	  the speed.
Xinode.c:
X	o Included boot.h and changed message about out of inodes on device.
Xmain.c:
X	o Included boot.h.
X	o Deleted constants involving memory sizes.
X	  Only the kernel should know them.
X	o Added and called get_boot_parameters.
X	o Changed get_base to get_physbase, added get_physbase.
X	  FS shouldn't know about memory, let alone segments.
X	  Better if the kernel did the checking (for DMA boundaries.)
X	o Added logic for skipping load of RAM disk when ram disk is not root.
X	o Deleted code telling MM where to put RAM disk.
X	  MM now tells FS.
X	o Added code to boot fast by prefetching blocks at good interleave.
X	  FLOPPY is not smart enough to do this.
Xmisc.c:
X	o Included boot.h.
Xpipe.c:
X	o Fixed unpause bug.
X	  CANCEL used open mode and not current i/o mode.
X	o Fixed another unpause bug.
X	  CANCEL did not go through dev switch, so pseudo-devices
X	  like /dev/tty were mishandled.
Xsuper.c:
X	o Included boot.h.
Xtable.c:
X	o Changed comment involving boot device numbers.
Xutility.c:
X	o Included boot.h.
END_OF_FILE
if test 1602 -ne `wc -c <'fsdif/CHANGES'`; then
    echo shar: \"'fsdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'fsdif/CHANGES'
fi
if test -f 'hdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hdif/CHANGES'\"
else
echo shar: Extracting \"'hdif/CHANGES'\" \(1334 characters\)
sed "s/^X//" >'hdif/CHANGES' <<'END_OF_FILE'
Xboot.h:
X	o Added it.
Xcom.h:
X	o Added IDLE task to let kernel do better accounting.
X	  It is split off from the HARDWARE task.
X	  Accounting can now be done for the hardware interrupts and context
X	  switching since most interrupt handling is now done with (clock)
X	  interrupts enabled.
X	  Eventually, IDLE could be a user task and do something more
X	  interesting.
X	o Deleted obsolete DISKINT and CLOCK_INT.
X	  These are replaced by a single HARD_INT.
X	  TTY_CHAR_INT and TTY_O_DONE should be obsolete but are not since
X	  TTY and PRINTER still use them instead of the correct HARD_INT.
X	o Added PORT_DEV, minor number for dev/port.
X	  The old port_in and port_out are denied to users in protected	mode.
X	o Added functions SYS_GBOOT, SYS_UMAP and SYS_MEM to SYSTASK.
Xconst.h:
X	o Increased NR_TASKS by 1 for IDLE.
X	o Doubled NR_PROCS for room.
X	  Optional.
X	o Changed CLICK_SIZE to 256 to allow access to 16MB on 386's and
X	  286's.
X	  This should probably be the standard, since it matches the ST
X	  value and shifting by 8 is (or should be) easier than by 4.
X	  The advantage of matching the hardware click size of 16 is
X	  superficial.
X	o Added macros to convert between clicks and kbytes.
X	  These are mainly used when printing values for the user.
X	o Deleted BOOT_DEV and ROOT_DEV.
X	  These are now variables, defined in boot.h.
END_OF_FILE
if test 1334 -ne `wc -c <'hdif/CHANGES'`; then
    echo shar: \"'hdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'hdif/CHANGES'
fi
if test -f 'libdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libdif/CHANGES'\"
else
echo shar: Extracting \"'libdif/CHANGES'\" \(344 characters\)
sed "s/^X//" >'libdif/CHANGES' <<'END_OF_FILE'
Xhead.s:
X	o Increased the stack size and documented all the register slots
X	  needed (stack size is too small mainly for separate I&D - fixed
X	  and reported a while ago).
X	o Put CLICK_SHIFT at locations 2-3 in the data.
X	  WARNING! It is hard coded as 8 since head.s is not (yet) set
X	  up to include h/const.h like the kernel assembler files.
END_OF_FILE
if test 344 -ne `wc -c <'libdif/CHANGES'`; then
    echo shar: \"'libdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'libdif/CHANGES'
fi
if test -f 'mmdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/CHANGES'\"
else
echo shar: Extracting \"'mmdif/CHANGES'\" \(1851 characters\)
sed "s/^X//" >'mmdif/CHANGES' <<'END_OF_FILE'
XGeneral:
X	o CLICK-SIZE now 256 for PC's, AT's and ST's.
X	  This is a complicated system-wide change for PC's and AT's.
X	  It is needed mainly so MM's tables can handle extended memory on
X	  AT's (now normal memory with the 286 kernel).
X	  The change doesn't affect the internals of MM much - a few things
X	  depended on CLICK_SIZE <= 1024, and everything still depends on
X	  it being a power of 2.
Xalloc.c:
X	o Changed mem_init() to get memory sizes from kernel.
X	  It used to be passed a single parameter, but now there are multiple
X	  sizes.
X	o Changed mem_init() to handle fragmented memory.
X	  The fragments are needed for AT extended memory and ROM shadow
X	  memory on AT's.
X	o Added mem_left() to count total memory left.
X	  This is currently only used to get the amount left after
X	  initialization for printing in the startup message.
Xmain.c:
X	o Changed do_brk2() to handle fragmented memory.
X	o Allocated extended memory RAM disk in do_brk2().
X	  The 1.3 MM was not able to handle extended memory, so FS only told
X	  MM about RAM disks in normal memory.
X	  Now, FS doesn't know about extended memory, and MM knows only
X	  enough to prefer it for allocating the RAM disk.
X	  This means that the extended memory RAM disk is lost with the old
X	  CLICK_SIZE of 16.
X	  Only unprotected mode 286's and 386's can have extended memory, and
X	  the protected mode kernel is supposed to make those modes obsolete.
X	o Replaced get_tot_mem() with get_mem().
X	  The i8088 version requires a new system call (SYS_MEM) to the
X	  system task.
X	  The version in getutil.s is obsolete (the wrong way to do it).
X	  The ST code is changed but not tested (it doesn't use SYS_MEM but
X	  should).
Xsignal.c:
X	o Added call to sys_sig() to tell kernel that signal handling is done.
X	  This helps fix the bug which allowed processes undergoing signal
X	  handling to run.
END_OF_FILE
if test 1851 -ne `wc -c <'mmdif/CHANGES'`; then
    echo shar: \"'mmdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'mmdif/CHANGES'
fi
if test -f 'toolsdif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toolsdif/CHANGES'\"
else
echo shar: Extracting \"'toolsdif/CHANGES'\" \(524 characters\)
sed "s/^X//" >'toolsdif/CHANGES' <<'END_OF_FILE'
Xbuild.c:
X	o The 1.3 version needed massive changes since it fails miserably
X	  when CLICK_SIZE != 16.
X	o This version also puts symbol tables into the image.
X	o It also has #ifdef'ed code to handle old Xenix a.out headers.
X	  Minix headers are handled very untidily here and in fs/exec.c.
Xfsck.c:
X	o Initialized default boot parameters and allowed user to change them.
X	o Eliminated non-portable preprocessor quoting trick.
X	  Printk should be used for further simplifications.
Xfsck1.s:
X	o Passed boot parameters to kernel.
END_OF_FILE
if test 524 -ne `wc -c <'toolsdif/CHANGES'`; then
    echo shar: \"'toolsdif/CHANGES'\" unpacked with wrong size!
fi
# end of 'toolsdif/CHANGES'
fi
if test -f 'commandsdif/readclock.c.cd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'commandsdif/readclock.c.cd'\"
else
echo shar: Extracting \"'commandsdif/readclock.c.cd'\" \(2780 characters\)
sed "s/^X//" >'commandsdif/readclock.c.cd' <<'END_OF_FILE'
X*** commands-1.3/readclock.c	Wed Oct  5 22:29:09 1988
X--- commands/readclock.c	Thu Jan 19 07:09:40 1989
X***************
X*** 132,136 ****
X  
X!   port_out( CLK_ELE, reg_addr );
X!   port_in(CLK_IO, &val);
X    return( val );
X  }
X--- 132,219 ----
X  
X!   if ( port_out( CLK_ELE, reg_addr ) < 0 || port_in(CLK_IO, &val) < 0 ) {
X!     printf( "-q\n" );
X!     exit( 1 );
X!   }
X    return( val );
X+ }
X+ 
X+ 
X+ /***********************************************************************/
X+ /*                                                                     */
X+ /*    Peek and poke using /dev/mem.                                    */
X+ /*    Callers now ought to check the return values.                    */
X+ /*    In Minix 1.3c, /dev/mem is incorrectly truncated to 640K,        */
X+ /*    so the CPU type byte is not accessable.                          */
X+ /*                                                                     */
X+ /***********************************************************************/
X+ 
X+ long lseek();
X+ 
X+ int peek( seg, offset )
X+ unsigned seg;
X+ unsigned offset;
X+ {
X+   static int memfd = -1;
X+   unsigned char val;
X+ 
X+   if ( memfd < 0 )
X+     memfd = open( "/dev/mem", 0 );
X+   if ( lseek( memfd, (unsigned long) seg * 0x10 + offset, 0 ) < 0 ||
X+        read( memfd, &val, 1 ) != 1 )
X+     return -1;
X+   return val;
X+ }
X+ 
X+ int poke( seg, offset, val )
X+ unsigned seg;
X+ unsigned offset;
X+ unsigned char val;
X+ {
X+   static int memfd = -1;
X+ 
X+   if ( memfd < 0 )
X+     memfd = open( "/dev/mem", 1 );
X+   if ( lseek( memfd, (unsigned long) seg * 0x10 + offset, 0 ) < 0 ||
X+        write( memfd, &val, 1 ) != 1 )
X+     return -1;
X+   return val ;
X+ }
X+ 
X+ 
X+ /***********************************************************************/
X+ /*                                                                     */
X+ /*    Port i/o functions using /dev/port.                              */
X+ /*    Callers now ought to check the return values.                    */
X+ /*                                                                     */
X+ /***********************************************************************/
X+ 
X+ long lseek();
X+ 
X+ int port_in( port, valp )
X+ unsigned port;
X+ unsigned *valp;
X+ {
X+   static int portfd = -1;
X+   unsigned char val;
X+ 
X+   if ( portfd < 0 )
X+     portfd = open( "/dev/port", 0 );
X+   if ( lseek( portfd, (long) port, 0 ) < 0 ||
X+        read( portfd, &val, 1 ) != 1 )
X+     return *valp = -1;
X+   return *valp = val;
X+ }
X+ 
X+ int port_out( port, val )
X+ unsigned port;
X+ unsigned char val;
X+ {
X+   static int portfd = -1;
X+ 
X+   if ( portfd < 0 )
X+     portfd = open( "/dev/port", 1 );
X+   if ( lseek( portfd, (long) port, 0 ) < 0 ||
X+        write( portfd, &val, 1 ) != 1 )
X+     return -1;
X+   return val ;
X  }
END_OF_FILE
if test 2780 -ne `wc -c <'commandsdif/readclock.c.cd'`; then
    echo shar: \"'commandsdif/readclock.c.cd'\" unpacked with wrong size!
fi
# end of 'commandsdif/readclock.c.cd'
fi
if test -f 'fsdif/at_makefile.cd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/at_makefile.cd'\"
else
echo shar: Extracting \"'fsdif/at_makefile.cd'\" \(742 characters\)
sed "s/^X//" >'fsdif/at_makefile.cd' <<'END_OF_FILE'
X*** fs-1.3/at_makefile	Wed Oct  5 21:55:48 1988
X--- fs/at_makefile	Wed Mar 22 03:41:32 1989
X***************
X*** 23,24 ****
X--- 23,25 ----
X  cache.s:	$h/error.h
X+ cache.s:	$h/boot.h
X  cache.s:	buf.h
X***************
X*** 49,50 ****
X--- 50,52 ----
X  inode.s:	$h/error.h
X+ inode.s:	$h/boot.h
X  inode.s:	buf.h
X***************
X*** 69,70 ****
X--- 71,73 ----
X  main.s:		$h/error.h
X+ main.s:		$h/boot.h
X  main.s:		buf.h
X***************
X*** 81,82 ****
X--- 84,86 ----
X  misc.s:		$h/error.h
X+ misc.s:		$h/boot.h
X  misc.s:		buf.h
X***************
X*** 164,165 ****
X--- 168,170 ----
X  super.s:	$h/error.h
X+ super.s:	$h/boot.h
X  super.s:	buf.h
X***************
X*** 194,195 ****
X--- 199,201 ----
X  utility.s:	$h/error.h
X+ utility.s:	$h/boot.h
X  utility.s:	buf.h
END_OF_FILE
if test 742 -ne `wc -c <'fsdif/at_makefile.cd'`; then
    echo shar: \"'fsdif/at_makefile.cd'\" unpacked with wrong size!
fi
# end of 'fsdif/at_makefile.cd'
fi
if test -f 'fsdif/device.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/device.c.cdif'\"
else
echo shar: Extracting \"'fsdif/device.c.cdif'\" \(296 characters\)
sed "s/^X//" >'fsdif/device.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/device.c	Wed Aug  3 21:05:11 1988
X--- fs/device.c	Sun Dec 18 04:34:36 1988
X***************
X*** 125,126 ****
X--- 125,127 ----
X    m1.TTY_FLAGS = dev_mess.TTY_FLAGS;	/* flags */
X+   m1.TTY_SPEED = dev_mess.TTY_FLAGS >> 16;	/* kludge for V1.2 TIOCGETP */
X    return(dev_mess.REP_STATUS);
END_OF_FILE
if test 296 -ne `wc -c <'fsdif/device.c.cdif'`; then
    echo shar: \"'fsdif/device.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/device.c.cdif'
fi
echo shar: End of archive 1 \(of 10\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 2 - By Bruce Evans
Message-ID: <5264@ditmela.oz>
Date: 18 May 89 01:20:45 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1220


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 10)."
# Contents:  kerneldif/CHANGES fsdif/cache.c.cdif fsdif/inode.c.cdif
#   fsdif/main.c.cdif fsdif/misc.c.cdif fsdif/pipe.c.cdif
#   fsdif/super.c.cdif fsdif/table.c.cdif fsdif/utility.c.cdif
#   hdif/boot.h.cdif hdif/com.h.cdif hdif/const.h.cdif
#   kerneldif/Bconsole.c.cdi kerneldif/Brs232.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:33:48 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/CHANGES'\"
else
echo shar: Extracting \"'kerneldif/CHANGES'\" \(13586 characters\)
sed "s/^X//" >'kerneldif/CHANGES' <<'END_OF_FILE'
XGeneral:
X	o Used the macros in proc.h to avoid magic numbers all over.
X	  The old macro for proc_addr() was slow (array indexing).
X	  The old conversion from a proc pointer to a proc number was even
X	  slower (pointer subtraction).
X	  The new macro for proc_addr() is unfortunately slower for constant
X	  process numbers so cproc_addr() is used for those.
X	o Eliminated most of the hardware segment arithmetic.
X	  This was the main thing standing between the C code and protected
X	  mode.
X	  WARNING: Amoeba still has some, so won't work with this kernel.
X	o Changed interrupt handling to better suit level sensitive
X	  interrupts on PS/2's and to reduce latency.
X	  WARNING: even PS/2-30's (which used to work) may be broken.
X	  WARNING: The ethernet driver needs some minor changes to match.
X	o Converted all assembler (.s) files to preprocessor (.x) files.
X	  This greatly simplifies the maintenance of constants across C and
X	  assembler code.
X	  The header file 'sglo.h' is used to centralize all declarations
X	  of assembler variables. 
X	o Started to remove saving and restoring of the interrupt enable
X	  state (1.2 did it better).
X	  The state should always be known since disabling interrupts for a
X	  whole function call is bad.
Xaxmakefile:
X	o NEW, the complicated makefile which I use to build many variations
X	  of the kernel.
X	  See the installation guide.
Xconst.h:
X	o Changed almost everything.
X	o INIT_SP is fixed.
X	o Hardware VECTOR's are parametrized by IRQ's since this kernel needs
X	  to change the vector bases.
X	o Introduced HCLICK_SIZE since CLICK_SIZE was being confused with
X	  the hardware click size.
X	o Made the requirement for stack alignment explicit.
Xglo.h:
X	o Removed globals realtime, lost_ticks, cur_proc, prev_proc, int_mess.
X	  Interrupt() no longer has to know about the internals of the
X	  clock task.
X	  Much time is saved by always using proc_ptr to access the current
X	  process.
X	  Interrupt messages are no longer necessary, they are passed around
X	  as numbers.
X	o Added some new globals and centralized some other declarations.
X	  Things like umap() are redeclared too often.
X	  The 'snow' flag should be set for cheap CGA's (in console.c).
X	  The old console driver incorrectly assumed snow removal was
X	  necessary on non-mono non-EGA's.
Xproc.h:
X	o Replaced the array of registers by a union and merged the pc_psw
X	  structure with it.
X	  It was inconsistent to treat pc_psw specially (the processor
X	  decides the order of pc_psw but in practice pc_psw is copied
X	  elsewhere in real mode and the processor decides the best order
X	  of all the registers in protected mode).
X	  The union could be a structure in this implementation.
X	o Added fields for p_ldt_sel and p_ldt for protected mode segments.
X	o Added fields p_int_blocked, p_int_held and p_next_held for new
X	  interrupt handling.
X	o Added field p_pendcount and defined SIG_PENDING for signal handling
X	  bug fix.
X	o Defined many macros to eliminate magic numbers.
X	o Eliminated busy_map and task_message globals.
X	  The use of these was the worst bottleneck in the old interrupt().
Xsconst.h:
X	o NEW, constants and macros not already defined in the C header
X	  files are defined here along with some macros for 286 code.
X	  There are also macros to let me use my 386 assembler instead
X	  of asld.
X	  Unfortunately, DOS assemblers like MASM are too different to
X	  use the same trick.
X	  Unfortunately, asld wants "[]" for parentheses in expressions,
X	  so some of the C definitions had to be explicit constants
X	  rather than expressions, to avoid breaking either cc or asld.
X	o WARNING: there are still lots of magic numbers in the old klib88
X	  code.
Xsglo.h:
X	o NEW, ALL globals used by the assembler code are declared here.
X	  A macro trick like "#define EXTERN" for the C code is used to
X	  set up the correct .define's and .extern's.
Xtype.h:
X	o Deleted struct pc_psw (now part of stack frame structure).
X	o Deleted struct sig_info (already no longer used).
X	o Added typedef's for scalar types of size 8, 16, 32 bits.
X	  Using chars, shorts, ints and longs directly leaves too many
X	  things dependent on the compiler.
X	o Added stack frame structure suitable for 8088 through 80286.
X	o Added segment descriptor structure for protected mode.
X	  Most protected mode things are in protect.h and protect.c, but
X	  this structure is needed in the process table.
Xat_wini.c:
X	o Deleted all explicit locking.
X	  The task provides adequate protection.
X	o Changed dma_read() to port_read() for protected mode.
X	o Same for dma_write().
X	o Fixed bug with port_read() and win_results() done in wrong order.
X	  The interrupt happens when the data is ready, not when it is read.
X	o Changed win_results() to old_win_results() so new one could do more.
X	o Wrapped some code with #ifdef STUPID_WINI_ADJUST.
X	  The offending code causes the first sector on partitions starting
X	  on an odd boundary to be lost.
X	  There is still a problem if the total number of sectors on the
X	  partition is odd.
X	o Added a new win_results() for the new interrupt handling scheme.
X	  Same as old one except that it clears the AT wini interrupt mask.
X	  There are too many exit points in the old win_results() to do this
X	  conveniently directly.
Xclock.c:
X	o Replaced CLOCK_TICK with HARD_INT.
X	  It was slower to distinguish them.
X	o Deleted FLUSH_MASK and flush_flag.
X	  They really belong to TTY.
X	o Defined TIMER_COUNT for cleaner init.
X	o Made globals realtime and lost_ticks into private variables.
X	  The locking is tricky enough when they are private!
X	  Lost_ticks is renamed pending_ticks and made a long.
X	o Moved printer restart logic to PRINTER task.
X	o Rewrote init_clock().
X	o Did accounting() inline.
X	o Added low level clock interrupt handler.
X	  See code for comments - there are many races to guard against.
Xconsole.c:
X	  WARNING: These changes are half-hearted since I usually use the
X	  console.c posted with my tty driver.
X	o Extra initialization for protected mode.
X	  Special video segments have to be used for protected mode.
X	  COLOR_BASE and MONO_BASE are defined (differently, in phys_bytes)
X	  in const.h for experimentally using screen memory for programs.
X	o Added locking to keyboard().
X	  Keyboard() may now be interrupted by RS232.
X	o Removed segment arithmetic and replaced get_byte() by
X	  get_physbyte() for protected mode.
X	o Added enable_irq() so main.c doesn't have to enable keyboard
X	  interrupt too early.
X	o Added scan_keyboard() for wreboot to use.
Xdmp.c:
X	o Changed output formatting for larger numbers in protected mode.
X	o Changed references to registers in process table.
X	o Cleaned up click to K conversions.
X	o Fixed wild array index in aout[NSIZE].
X	o Made other unnecessary changes to simplify code.
Xexception.c:
X	o NEW, replaces some exception handlers in main.c
X	  This should eventually contain stack fault handlers and page
X	  fault handlers, etc.
Xfloppy.c:
X	o Deleted redundant olivetti variable.
X	o Deleted all explicit locking, changed fdc_results().
X	  Same as for at_wini.c
Xi8259.c:
X	o NEW, handles initialization of the interrupt controller.
X	  Needed since the BIOS init mixes hardware interrupts into vectors
X	  reserved for exceptions (and used on 286's and above).
Xklib286.x:
X	o NEW, duplicates all functions in klib88.x which have to be
X	  implemented differently in protected mode.
X	  It contains an initialization routine which applies the necessary
X	  patches.
Xklib88.x:
X	o NEW, a rewrite of klib88.s.
X	  Many routines are new or totally rewritten and/or renamed
X	  for compatibility with protected mode.
X	  WARNING: klib88.s will be obliterated when 'make' is run.
Xmain.c:
X	o Moved trap() and unexpected_int() to exception.c.
X	o Included boot.h to get at limit on processor type.
X	  386 and 286 systems need to be run as 8088's for testing.
X	o Included debugger support.
X	  Rest of debugger is not in this posting.
X	o Made many small changes.
X	  The memory maps were not initialized right.
X	  The 8259 mask was not initialized right.
Xmemory.c:
X	o Fixed bugs in initialization of /dev/kmem.
X	  The bad use of get_base() is a good example of how the wrong
X	  approach leads to trouble for protected mode - and larger changes.
X	o Initialized /dev/mem with size depending on processor.
X	  WARNING: the inode has the wrong size of 640K.
X	o Added /dev/port.
X	o Deleted special treatment of extended memory.
X	  Phys_copy() has extra intelligence to deal with it, and MM
X	  can map it now CLICK_SIZE is 256.
Xmisc.c:
X	o NEW, now contains only a routine to initialize tables of memory.
Xmpx286.x:
X	o NEW, duplicates all interrupt handlers and functions in mpx88.x
X	  which have to be implemented differently in protected mode.
X	  A few patches are necessary (they are done by klib286).
X	  The interrupt vectors do not need patching since a new interrupt
X	  table is set up in protect.c and loaded just once in p_restart.
Xmpx88.x:
X	o NEW, a rewrite of mpx88.s.
X	o The startup code copies the boot parameters (if any) provided by
X	  the boot loader.
X	o All interrupt handlers now use the 8259 to stop nested interrupts
X	  from the same device, but allow interrupts from other devices.
X	o Save and restart are rewritten for speed and to save registers
X	  in the same order as for protected mode (where the correct order
X	  is more important).
Xprinter.c:
X	  WARNING: these changes are not well tested since I rarely use the
X	  printer.
X	o Fixed bug with no reply in default case of message handler.
X	o Changed locking to use mask rather than lock everything.
X	  The printer code is still awful.
X	o Eliminated segment arithmetic as for console.c.
X	o Put message content in variable 'done_status' since new interrupt
X	  messages can have no content.
X	o Checked for printer restart here instead of clock.c.
X	  The locking is very tricky and it is best for clock.c not to know.
Xproc.c:
X	o Converted most of the public routines to locked variants.
X	  The way the system task (privilege 1 in protected mode) calls
X	  the kernel (context switcher, privilege 0) is potentially
X	  dangerous.
X	o Rewrote interrupt() for speed.
X	  The method is simpler (particularly the way blocked interrupts
X	  are dispatched by the check in mini_rec()), but this is obscured
X	  by the complications needed to allow interrupt() to run with
X	  interrupts enabled.
X	o Made many small changes to use proc pointers instead of proc
X	  numbers.
X	o Passed return code from syscall() back to assembly code to handle.
X	  This is faster and reduces the number of registers that the C
X	  code has to know about.
X	o Speeded up most of the smaller functions by avoiding index
X	  calculations.
X	o Simplified pick_proc() by making IDLE a normal process.
X	o Added function unhold() to finish off the new interrupt handling.
Xprotect.c:
X	o NEW, initialization and segment building for protected mode.
Xprotect.h:
X	o NEW, various constants for protected mode.
Xrs2.x:
X	o NEW, replaces rs2.s for my tty driver.
Xrs232.c:
X	  WARNING: These changes are half-hearted since I usually use the
X	  rs232.c posted with my tty driver.
X	  This one remains full of bugs, mostly old but it's hard to tell.
X	o Added lock()'s after calling interrupt() since new interrupt()
X	  may unlock().
X	o Eliminated segment arithmetic as for console.c.
X	o Fix attempted lock() around whole system call in tty_o_done().
X	  The new syscall handler unlocks, so a safer lock is required.
X	o Added glue routines to match new interrupt handling.
Xsystem.c:
X	o Added SYS_GBOOT, SYS_UMAP and SYS_MEM system calls.
X	  SYS_GBOOT to pass boot parameters to FS.
X	  SYS_UMAP and SYS_MEM to replace improper memory handling in FS
X	  and MM.
X	o Changed references to registers in process table.
X	  WARNING: the types used by MM to share the stack pointer and
X	  signal catcher are bogus.
X	  There is only a conventional relationship between C pointers
X	  and machine registers.
X	o Made many small changes to use register pointers more and eliminate
X	  local variables.
X	o Locked access to user and system times in do_exec() and do_times().
X	  This is necessary because these times are now updated below the
X	  task level in the clock interrupt handler.
X	o Changed do_fork(), do_exec(), do_sig() and cause_sig() as part
X	  of fix of signal handling bug.
X	  Processes undergoing signal handling are now kept off the ready
X	  queue by the SIG_PENDING flag and the p_pendcount count.
X	  MM has to send a message to say it is finished.
X	  A kludged form of SYS_SIG is used.
X	o Called lockpick_proc() from inform() to run MM soon if inform()
X	  was invoked by an exception in a user process.
X	o Added alloc_segments().
X	  All segment register setup is now done here.
X	  This is the only place in the old C code which is fundamentally
X	  different for protected mode.
Xtable.c:
X	o Added IDLE task.
X	o Moved declaration of kernel stack to assembler code.
X	o Used a char array to allocate task stacks out of.
X	  The int array is only a kludge for word alignment and complicates
X	  the arithmetic in main.c and is inadequate for doubleword
X	  alignment for 386's.
Xtty.c:
X	  WARNING: These changes are half-hearted since I usually use the
X	  tty.c posted with my tty driver.
X	  There a few known bugs in tty, but it's probably safe to use it
X	  with the console driver (but not RS232).
X	o Avoided getting the tty_driver_buf pointer out of the interrupt
X	  message since the new interrupt messages can have no content.
Xxt_wini.c:
X	o Deleted all explicit locking, changed win_results().
X	  Same as for at_wini.c
X	o Fixed the misspelled copy_param.
X	  This bug has been known for years.
X	o Wrapped some code with #ifdef STUPID_WINI_ADJUST, as for at_wini.c.
END_OF_FILE
if test 13586 -ne `wc -c <'kerneldif/CHANGES'`; then
    echo shar: \"'kerneldif/CHANGES'\" unpacked with wrong size!
fi
# end of 'kerneldif/CHANGES'
fi
if test -f 'fsdif/cache.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/cache.c.cdif'\"
else
echo shar: Extracting \"'fsdif/cache.c.cdif'\" \(629 characters\)
sed "s/^X//" >'fsdif/cache.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/cache.c	Wed Aug  3 21:05:10 1988
X--- fs/cache.c	Thu Jul  7 00:53:11 1988
X***************
X*** 17,18 ****
X--- 17,19 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
X***************
X*** 212,217 ****
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	if (sp->s_dev == ROOT_DEV)
X! 		printf("No space on root device (RAM disk)\n");
X! 	else
X! 		printf("No space on device %d/%d\n", major, minor);
X  	return(NO_ZONE);
X--- 213,216 ----
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	printf("No space on %sdevice %d/%d\n",
X! 		sp->s_dev == ROOT_DEV ? "root " : "", major, minor);
X  	return(NO_ZONE);
END_OF_FILE
if test 629 -ne `wc -c <'fsdif/cache.c.cdif'`; then
    echo shar: \"'fsdif/cache.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/cache.c.cdif'
fi
if test -f 'fsdif/inode.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/inode.c.cdif'\"
else
echo shar: Extracting \"'fsdif/inode.c.cdif'\" \(651 characters\)
sed "s/^X//" >'fsdif/inode.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/inode.c	Thu Oct  6 22:19:28 1988
X--- fs/inode.c	Fri Oct  7 22:28:02 1988
X***************
X*** 17,18 ****
X--- 17,19 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
X***************
X*** 118,123 ****
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	if (sp->s_dev == ROOT_DEV)
X! 		printf("Out of i-nodes on root device (RAM disk)\n");
X! 	else
X! 		printf("Out of i-nodes on device %d/%d\n", major, minor);
X  	return(NIL_INODE);
X--- 119,122 ----
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	printf("Out of i-nodes on %sdevice %d/%d\n",
X! 		sp->s_dev == ROOT_DEV ? "root " : "", major, minor);
X  	return(NIL_INODE);
END_OF_FILE
if test 651 -ne `wc -c <'fsdif/inode.c.cdif'`; then
    echo shar: \"'fsdif/inode.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/inode.c.cdif'
fi
if test -f 'fsdif/main.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/main.c.cdif'\"
else
echo shar: Extracting \"'fsdif/main.c.cdif'\" \(7501 characters\)
sed "s/^X//" >'fsdif/main.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/main.c	Thu Oct  6 22:25:19 1988
X--- fs/main.c	Wed Mar 22 15:15:27 1989
X***************
X*** 19,20 ****
X--- 19,21 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
X***************
X*** 39,42 ****
X  #ifdef i8088
X! #define EM_ORIGIN   0x100000	/* origin of extended memory RAM disk on AT */
X! #define MAX_CRD           255	/* if root fs > MAX_CRD, use extended mem */
X  #endif
X--- 40,42 ----
X  #ifdef i8088
X! FORWARD phys_bytes get_physbase();
X  #endif
X***************
X*** 143,145 ****
X    buf_pool();			/* initialize buffer pool */
X!   load_ram();			/* Load RAM disk from root diskette. */
X    load_super();			/* Load super block for root device */
X--- 143,146 ----
X    buf_pool();			/* initialize buffer pool */
X!   get_boot_parameters();
X!   load_ram();			/* init RAM disk, load if it is root */
X    load_super();			/* Load super block for root device */
X***************
X*** 184,186 ****
X    phys_bytes org;
X-   extern phys_clicks get_base();
X  #endif
X--- 185,186 ----
X***************
X*** 203,205 ****
X    for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
X! 	org = get_base() << CLICK_SHIFT;	/* phys addr where FS is */
X  	low_off = (vir_bytes) bp->b_data;
X--- 203,205 ----
X    for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
X! 	org = get_physbase();	/* phys addr where FS is */
X  	low_off = (vir_bytes) bp->b_data;
X***************
X*** 232,235 ****
X  {
X! /* The root diskette contains a block-by-block image of the root file system
X!  * starting at 0.  Go get it and copy it to the RAM disk. 
X   */
X--- 232,236 ----
X  {
X! /* If the root device is the RAM disk, copy the entire root image device
X!  * block-by-block to a RAM disk with the same size as the image.
X!  * Otherwise, just allocate a RAM disk with size given in the boot parameters.
X   */
X***************
X*** 241,245 ****
X    block_nr i;
X!   dev_nr root_device;
X    phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks;
X-   long base;
X    extern phys_clicks data_org[INFO + 2];
X--- 242,245 ----
X    block_nr i;
X!   dev_nr root_device;		/* this should be called boot_device */
X    phys_clicks ram_clicks, init_org, init_text_clicks, init_data_clicks;
X    extern phys_clicks data_org[INFO + 2];
X***************
X*** 251,255 ****
X    init_data_clicks = data_org[INFO + 2];
X-   base = (long) init_org + (long) init_text_clicks + (long) init_data_clicks;
X-   base = base << CLICK_SHIFT;
X  
X    /* Get size of RAM disk by reading root file system's super block.
X--- 251,259 ----
X    init_data_clicks = data_org[INFO + 2];
X  
X+   /* If the root device is specified in the boot parameters, use it. */
X+   if (ROOT_DEV != DEV_RAM) {
X+ 	count = boot_parameters.bp_ramsize;
X+ 	goto got_root_dev;	/* kludge to avoid excessive indent/diffs */
X+   }
X+ 
X    /* Get size of RAM disk by reading root file system's super block.
X***************
X*** 279,297 ****
X    count = sp->s_nzones << sp->s_log_zone_size;	/* # blocks on root dev */
X    if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count);
X    ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE);
X-   put_block(bp, FULL_DATA_BLOCK);
X  
X- #ifdef i8088
X-   /* There are two possibilities now (by convention):  
X-    *    count < MAX_CRD  ==> RAM disk is in core
X-    *    count >=MAX_CRD  ==> RAM disk is in extended memory (AT only)
X-    * In the latter case, tell MM that RAM disk size is 0 and tell the ram disk
X-    * driver than the device begins at 1MB.
X-    */
X-   if (count > MAX_CRD) {
X- 	ram_clicks = 0;		/* MM does not have to allocate any core */
X- 	base = EM_ORIGIN;	/* tell RAM disk driver RAM disk origin */
X-   }
X- #endif
X- 
X    /* Tell MM the origin and size of INIT, and the amount of memory used for the
X--- 283,289 ----
X    count = sp->s_nzones << sp->s_log_zone_size;	/* # blocks on root dev */
X+   put_block(bp, FULL_DATA_BLOCK);
X+ got_root_dev:
X    if (count > MAX_RAM) panic("RAM disk is too big. # blocks = ", count);
X    ram_clicks = count * (BLOCK_SIZE/CLICK_SIZE);
X  
X    /* Tell MM the origin and size of INIT, and the amount of memory used for the
X***************
X*** 310,315 ****
X  
X!   /* Tell RAM driver where RAM disk is and how big it is. */
X    m1.m_type = DISK_IOCTL;
X    m1.DEVICE = RAM_DEV;
X-   m1.POSITION = base;
X    m1.COUNT = count;
X--- 302,308 ----
X  
X!   /* Tell RAM driver where RAM disk is and how big it is. The BRK2 call has
X!    * filled in the m1.POSITION field.
X!    */
X    m1.m_type = DISK_IOCTL;
X    m1.DEVICE = RAM_DEV;
X    m1.COUNT = count;
X***************
X*** 317,325 ****
X  
X    /* Copy the blocks one at a time from the root diskette to the RAM */
X- #ifdef i8088
X-   if (ram_clicks == 0) 	
X- 	printf("RAM disk of %d blocks is in extended memory\n\n", count);
X- #endif
X  #ifdef FASTLOAD
X!   fastload(root_device, (char *)base);
X  #else
X--- 310,318 ----
X  
X+   /* If the root device is not the RAM disk, it doesn't need loading. */
X+   if (ROOT_DEV != DEV_RAM)
X+ 	return;
X+ 
X    /* Copy the blocks one at a time from the root diskette to the RAM */
X  #ifdef FASTLOAD
X!   fastload(root_device, (char *) m1.POSITION);	/* assumes 32 bit pointers */
X  #else
X***************
X*** 327,328 ****
X--- 320,341 ----
X    for (i = 0; i < count; i++) {
X+ 	/* Prefetch blocks into cache according to interleave.
X+ 	 * The floppy driver should be rewritten to do this and should attain
X+ 	 * an interleave of 1 even on slow PC's.
X+ 	 * Here we can only handle interleave > 1.
X+ 	 * 2 is good for AT's, but nothing seems to help PC's.
X+ 	 * Assume standard DOS format with interleave of 1.
X+ 	 */
X+ #define N_PREFETCH 11		/* prime > blocks/track on all floppy types */
X+ #define INTERLEAVE  2
X+ 	if (i % N_PREFETCH == 0) {
X+ 		int j, k;
X+ 
X+ 		for (k = j = 0; j < N_PREFETCH; ++j, k += INTERLEAVE) {
X+ 			if (k > N_PREFETCH)
X+ 				k -= N_PREFETCH;
X+ 			if (i + k < count)
X+ 				put_block(get_block(root_device, i + k,
X+ 				                    NORMAL), NORMAL);
X+ 		}
X+ 	}
X  	bp = get_block(root_device, (block_nr) i, NORMAL);
X***************
X*** 338,340 ****
X  
X!   if (root_device == BOOT_DEV)
X  	printf("\rRAM disk loaded.    Please remove root diskette.           \n\n");
X--- 351,353 ----
X  
X!   if ( ((root_device ^ DEV_FD0) & ~BYTE) == 0 )
X  	printf("\rRAM disk loaded.    Please remove root diskette.           \n\n");
X***************
X*** 506 ****
X--- 519,559 ----
X  #endif FASTLOAD
X+ 
X+ /*===========================================================================*
X+  *				get_boot_parameters			     *
X+  *===========================================================================*/
X+ PUBLIC struct bparam_s boot_parameters =  /* overwritten if new kernel */
X+ {
X+   DROOTDEV, DRAMIMAGEDEV, DRAMSIZE, DSCANCODE,
X+ };
X+ 
X+ PRIVATE get_boot_parameters()
X+ {
X+ /* Ask kernel for boot parameters. */
X+ 
X+   struct bparam_s temp_parameters;
X+ 
X+   m1.m_type = SYS_GBOOT;
X+   m1.PROC1 = FS_PROC_NR;
X+   m1.MEM_PTR = (char *) &temp_parameters;
X+   if (sendrec(SYSTASK, &m1) == OK && m1.m_type == OK)
X+ 	boot_parameters = temp_parameters;
X+ }
X+ 
X+ #ifdef i8088
X+ /*===========================================================================*
X+  *				get_physbase				     *
X+  *===========================================================================*/
X+ PRIVATE phys_bytes get_physbase()
X+ {
X+ /* Ask kernel for base of fs data space. */
X+ 
X+   m1.m_type = SYS_UMAP;
X+   m1.SRC_PROC_NR = FS_PROC_NR;
X+   m1.SRC_SPACE = D;
X+   m1.SRC_BUFFER = 0;
X+   m1.COPY_BYTES = 1;
X+   if (sendrec(SYSTASK, &m1) != OK || m1.SRC_BUFFER == 0)
X+ 	panic("Can't get fs base", NO_NUM);
X+   return m1.SRC_BUFFER;
X+ }
X+ #endif
END_OF_FILE
if test 7501 -ne `wc -c <'fsdif/main.c.cdif'`; then
    echo shar: \"'fsdif/main.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/main.c.cdif'
fi
if test -f 'fsdif/misc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/misc.c.cdif'\"
else
echo shar: Extracting \"'fsdif/misc.c.cdif'\" \(200 characters\)
sed "s/^X//" >'fsdif/misc.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/misc.c	Wed Aug  3 21:05:13 1988
X--- fs/misc.c	Thu Jul  7 02:14:48 1988
X***************
X*** 18,19 ****
X--- 18,20 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
END_OF_FILE
if test 200 -ne `wc -c <'fsdif/misc.c.cdif'`; then
    echo shar: \"'fsdif/misc.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/misc.c.cdif'
fi
if test -f 'fsdif/pipe.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/pipe.c.cdif'\"
else
echo shar: Extracting \"'fsdif/pipe.c.cdif'\" \(733 characters\)
sed "s/^X//" >'fsdif/pipe.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/pipe.c	Wed Aug  3 21:05:15 1988
X--- fs/pipe.c	Wed Oct 26 21:08:12 1988
X***************
X*** 23,24 ****
X--- 23,25 ----
X  #include "type.h"
X+ #include "dev.h"
X  #include "file.h"
X***************
X*** 247,251 ****
X  	mess.PROC_NR = proc_nr;
X! 	mess.COUNT = f->filp_mode;	/* tell kernel whether R or W */
X  	mess.m_type = CANCEL;
X! 	rw_dev(task, &mess);
X  	revive(proc_nr, EINTR);	/* signal interrupted call */
X--- 248,253 ----
X  	mess.PROC_NR = proc_nr;
X! 	/* Tell kernel whether R or W. Mode is from current call, not open. */
X! 	mess.COUNT = (rfp->fp_fd & BYTE) == READ ? R_BIT : W_BIT;
X  	mess.m_type = CANCEL;
X! 	(*dmap[(dev >> MAJOR) & BYTE].dmap_rw)(task, &mess);
X  	revive(proc_nr, EINTR);	/* signal interrupted call */
END_OF_FILE
if test 733 -ne `wc -c <'fsdif/pipe.c.cdif'`; then
    echo shar: \"'fsdif/pipe.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/pipe.c.cdif'
fi
if test -f 'fsdif/super.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/super.c.cdif'\"
else
echo shar: Extracting \"'fsdif/super.c.cdif'\" \(202 characters\)
sed "s/^X//" >'fsdif/super.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/super.c	Wed Aug  3 21:05:17 1988
X--- fs/super.c	Wed Feb 15 02:12:27 1989
X***************
X*** 19,20 ****
X--- 19,21 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
END_OF_FILE
if test 202 -ne `wc -c <'fsdif/super.c.cdif'`; then
    echo shar: \"'fsdif/super.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/super.c.cdif'
fi
if test -f 'fsdif/table.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/table.c.cdif'\"
else
echo shar: Extracting \"'fsdif/table.c.cdif'\" \(596 characters\)
sed "s/^X//" >'fsdif/table.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/table.c	Wed Aug  3 21:05:17 1988
X--- fs/table.c	Sat Oct 22 22:08:16 1988
X***************
X*** 117,119 ****
X   * next entry is major device 1, etc.  Character and block devices can be
X!  * intermixed at random.  If this ordering is changed, BOOT_DEV and ROOT_DEV
X   * must be changed to correspond to the new values.  Note that the major
X--- 117,119 ----
X   * next entry is major device 1, etc.  Character and block devices can be
X!  * intermixed at random.  If this ordering is changed, the devices in h/boot.h
X   * must be changed to correspond to the new values.  Note that the major
END_OF_FILE
if test 596 -ne `wc -c <'fsdif/table.c.cdif'`; then
    echo shar: \"'fsdif/table.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/table.c.cdif'
fi
if test -f 'fsdif/utility.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fsdif/utility.c.cdif'\"
else
echo shar: Extracting \"'fsdif/utility.c.cdif'\" \(206 characters\)
sed "s/^X//" >'fsdif/utility.c.cdif' <<'END_OF_FILE'
X*** fs-1.3/utility.c	Wed Aug  3 21:05:18 1988
X--- fs/utility.c	Wed Feb 15 02:09:50 1989
X***************
X*** 15,16 ****
X--- 15,17 ----
X  #include "../h/error.h"
X+ #include "../h/boot.h"
X  #include "const.h"
END_OF_FILE
if test 206 -ne `wc -c <'fsdif/utility.c.cdif'`; then
    echo shar: \"'fsdif/utility.c.cdif'\" unpacked with wrong size!
fi
# end of 'fsdif/utility.c.cdif'
fi
if test -f 'hdif/boot.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hdif/boot.h.cdif'\"
else
echo shar: Extracting \"'hdif/boot.h.cdif'\" \(1346 characters\)
sed "s/^X//" >'hdif/boot.h.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- h/boot.h	Wed Mar  1 14:26:46 1989
X***************
X*** 0 ****
X--- 1,43 ----
X+ /* boot.h */
X+ 
X+ /* Redefine root and root image devices as variables.
X+  * This keeps the diffs small but may cause future confusion.
X+  */
X+ #define BOOT_DEV   (boot_parameters.bp_ramimagedev)
X+ #define ROOT_DEV   (boot_parameters.bp_rootdev)
X+ 
X+ /* Device numbers of RAM, floppy and hard disk devices.
X+  * h/com.h defines RAM_DEV but only as the minor number.
X+  */
X+ #define DEV_FD0   0x200
X+ #define DEV_HD0   0x300
X+ #define DEV_RAM   0x100
X+ 
X+ /* Default device numbers for root and root image.
X+  * Root image is only used when root is /dev/ram.
X+  */
X+ #define DRAMIMAGEDEV (DEV_FD0 + 0)
X+ #define DROOTDEV  (DEV_RAM + 0)
X+ 
X+ /* Default RAM disk size.
X+  * Not used if root is /dev/ram when size is from root image.
X+  */
X+ #define DRAMSIZE   0
X+ 
X+ /* Default scan code to fake a PC keyboard. */
X+ #define DSCANCODE  13
X+ 
X+ /* Default processor type for no restriction (88 would force 386 to 88). */
X+ #define DPROCESSOR 0xFFFF
X+ 
X+ /* Structure to hold boot parameters. */
X+ struct bparam_s
X+ {
X+   dev_nr bp_rootdev;
X+   dev_nr bp_ramimagedev;
X+   unsigned bp_ramsize;
X+   unsigned bp_scancode;		/* still put into BX for kernel */
X+   unsigned bp_processor;
X+ };
X+ 
X+ extern struct bparam_s boot_parameters;
END_OF_FILE
if test 1346 -ne `wc -c <'hdif/boot.h.cdif'`; then
    echo shar: \"'hdif/boot.h.cdif'\" unpacked with wrong size!
fi
# end of 'hdif/boot.h.cdif'
fi
if test -f 'hdif/com.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hdif/com.h.cdif'\"
else
echo shar: Extracting \"'hdif/com.h.cdif'\" \(1355 characters\)
sed "s/^X//" >'hdif/com.h.cdif' <<'END_OF_FILE'
X*** h-1.3/com.h	Wed Aug  3 21:15:03 1988
X--- h/com.h	Thu Mar 23 01:39:55 1989
X***************
X*** 50,51 ****
X--- 50,53 ----
X  
X+ #define IDLE (AMOEBA_CLASS+1)	/* task to run when there's nothing to run */
X+ 
X  #define PRINTER           -7		/* printer  I/O class */
X***************
X*** 55,57 ****
X  #define FLOPPY            -5	/* floppy disk class */
X- #	define DISKINT     1	/* fcn code for disk interrupt */
X  #	define DISK_READ   3	/* fcn code to DISK (must equal TTY_READ) */
X--- 57,58 ----
X***************
X*** 65,66 ****
X--- 66,70 ----
X  #	define NULL_DEV    3	/* minor device for /dev/null */
X+ #ifdef i8088
X+ #	define PORT_DEV    4	/* minor device for /dev/port */
X+ #endif
X  
X***************
X*** 68,70 ****
X  #	define SET_ALARM   1	/* fcn code to CLOCK, set up alarm */
X- #	define CLOCK_TICK  2	/* fcn code for clock tick */
X  #	define GET_TIME	   3	/* fcn code to CLOCK, get real time */
X--- 72,73 ----
X***************
X*** 85,86 ****
X--- 88,92 ----
X  #	define SYS_KILL   11	/* fcn code for sys_kill(proc, sig) */
X+ #	define SYS_GBOOT  12	/* fcn code for sys_gboot(procno, bootptr) */
X+ #	define SYS_UMAP   13	/* fcn code for sys_umap(procno, etc) */
X+ #	define SYS_MEM    14	/* fcn code for sys_mem() */
X  
X***************
X*** 154 ****
X--- 160,162 ----
X  #endif AMOEBA
X+ 
X+ #define HARD_INT           2	/* fcn code for all hardware interrupts */
END_OF_FILE
if test 1355 -ne `wc -c <'hdif/com.h.cdif'`; then
    echo shar: \"'hdif/com.h.cdif'\" unpacked with wrong size!
fi
# end of 'hdif/com.h.cdif'
fi
if test -f 'hdif/const.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hdif/const.h.cdif'\"
else
echo shar: Extracting \"'hdif/const.h.cdif'\" \(1785 characters\)
sed "s/^X//" >'hdif/const.h.cdif' <<'END_OF_FILE'
X*** h-1.3/const.h	Thu Oct  6 03:32:57 1988
X--- h/const.h	Wed Jan 18 23:13:40 1989
X***************
X*** 31,37 ****
X  #ifdef AM_KERNEL
X! #define NR_TASKS	  13	/* must be 5 more than without amoeba */
X  #else
X! #define NR_TASKS           8	/* number of tasks in the transfer vector */
X  #endif
X! #define NR_PROCS          16	/* number of slots in proc table */
X  #define NR_SEGS            3	/* # segments per process */
X--- 31,37 ----
X  #ifdef AM_KERNEL
X! #define NR_TASKS	  14	/* must be 5 more than without amoeba */
X  #else
X! #define NR_TASKS           9	/* number of tasks in the transfer vector */
X  #endif
X! #define NR_PROCS          32	/* number of slots in proc table */
X  #define NR_SEGS            3	/* # segments per process */
X***************
X*** 45,48 ****
X  #ifdef i8088
X! #define CLICK_SIZE      0020	/* unit in which memory is allocated */
X! #define CLICK_SHIFT        4	/* log2 of CLICK_SIZE */
X  #endif
X--- 45,48 ----
X  #ifdef i8088
X! #define CLICK_SIZE       256	/* unit in which memory is allocated */
X! #define CLICK_SHIFT        8	/* log2 of CLICK_SIZE */
X  #endif
X***************
X*** 53,54 ****
X--- 53,62 ----
X  
X+ #define click_to_round_k(n) \
X+ 	((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
X+ #if CLICK_SIZE < 1024
X+ #define k_to_click(n) ((n) * (1024 / CLICK_SIZE))
X+ #else
X+ #define k_to_click(n) ((n) / (CLICK_SIZE / 1024))
X+ #endif
X+ 
X  /* Process numbers of some important processes */
X***************
X*** 77,82 ****
X  #define MAX_ISTACK_BYTES   2048	/* maximum initial stack size for EXEC */
X- 
X- /* Device numbers of root (RAM) and boot (fd0) devices. */
X- #define ROOT_DEV (dev_nr)   256	/* major-minor device number of root dev */
X- #define BOOT_DEV (dev_nr)   512	/* major-minor device number of boot diskette */
X  
X--- 85,86 ----
END_OF_FILE
if test 1785 -ne `wc -c <'hdif/const.h.cdif'`; then
    echo shar: \"'hdif/const.h.cdif'\" unpacked with wrong size!
fi
# end of 'hdif/const.h.cdif'
fi
if test -f 'kerneldif/Bconsole.c.cdi' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/Bconsole.c.cdi'\"
else
echo shar: Extracting \"'kerneldif/Bconsole.c.cdi'\" \(7608 characters\)
sed "s/^X//" >'kerneldif/Bconsole.c.cdi' <<'END_OF_FILE'
X*** kernel-1.3B/console.c	Mon Jan  2 03:07:19 1989
X--- kernel/console.c	Sun Mar 12 15:29:17 1989
X***************
X*** 13,14 ****
X--- 13,15 ----
X  #include "proc.h"
X+ #include "protect.h"
X  #include "tty.h"
X***************
X*** 20,23 ****
X  /* Definitions used by the console driver. */
X- #define COLOR_BASE    0xB800	/* video ram paragraph for color display */
X- #define MONO_BASE     0xB000	/* video ram address for mono display */
X  #define C_VID_MASK    0x3FFF	/* mask for 16K video RAM */
X--- 21,22 ----
X***************
X*** 164,165 ****
X--- 163,169 ----
X  
X+ #ifdef DEBUGGER
X+   /* Call debugger? (as early as practical, not in TTY which may be hung) */
X+   if (code == F10) db();
X+ #endif
X+ 
X    /* Store the character in memory so the task can get at it later. */
X***************
X*** 168,170 ****
X    if (kb->iptr < kb->ibufend) {
X! 	tty_events += EVENT_THRESHOLD;
X  	++kb->iptr;
X--- 172,176 ----
X    if (kb->iptr < kb->ibufend) {
X! 	lock();			/* protect shared variable */
X! 	tty_events += EVENT_THRESHOLD;	/* C doesn't guarantee atomic */
X! 	unlock();
X  	++kb->iptr;
X***************
X*** 275,276 ****
X--- 281,285 ----
X  
X+   if ( c >= ' ' )
X+ 	goto into_slow_switch;
X+ 
X    switch(c) {
X***************
X*** 329,330 ****
X--- 338,340 ----
X  	default:		/* printable chars are stored in ramqueue */
X+ into_slow_switch:
X  #ifndef LINEWRAP
X***************
X*** 825,826 ****
X--- 835,837 ----
X   */
X+ #if 0
X    port_out(vid_port + INDEX, reg);	/* set the index register */
X***************
X*** 829,830 ****
X--- 840,844 ----
X    port_out(vid_port + DATA, val&BYTE);	/* output low byte */
X+ #else
X+   porti_out(vid_port + INDEX, (reg + 1) | (reg << 8), val);
X+ #endif
X  }
X***************
X*** 933,935 ****
X    if (color) {
X! 	vid_base = COLOR_BASE;
X  	vid_mask = C_VID_MASK;
X--- 947,949 ----
X    if (color) {
X! 	vid_base = COLOR_BASE >> HCLICK_SHIFT;
X  	vid_mask = C_VID_MASK;
X***************
X*** 938,940 ****
X    } else {
X! 	vid_base = MONO_BASE;
X  	vid_mask = M_VID_MASK;
X--- 952,954 ----
X    } else {
X! 	vid_base = MONO_BASE >> HCLICK_SHIFT;
X  	vid_mask = M_VID_MASK;
X***************
X*** 949,950 ****
X--- 963,969 ----
X  
X+ #ifdef i80286
X+   if (processor >= 286)
X+ 	vid_base = color ? COLOR_SELECTOR : MONO_SELECTOR;
X+ #endif
X+ 
X    set_6845(CUR_SIZE, CURSOR_SHAPE);	/* set cursor shape */
X***************
X*** 971,972 ****
X--- 990,992 ----
X  
X+   scan_keyboard();		/* stop lockup from leftover keystroke */
X    set_leds();			/* don't accept BIOS state */
X***************
X*** 1024,1025 ****
X--- 1044,1046 ----
X  
X+ #ifndef DEBUGGER
X  /*===========================================================================*
X***************
X*** 1038,1039 ****
X--- 1059,1061 ----
X  }
X+ #endif /* DEBUGGER - putc() */
X  
X***************
X*** 1070 ****
X--- 1092,1234 ----
X  }
X+ 
X+ 
X+ /****************************************************************************/
X+ 
X+ 
X+ /* Bug fix for keyboard initialization. */
X+ 
X+ #ifndef DEBUGGER		/* debugger already has it */
X+ /*==========================================================================*
X+  *				scan_keyboard				    *
X+  *==========================================================================*/
X+ PUBLIC int scan_keyboard()
X+ {
X+   /* Fetch the character from the keyboard hardware and acknowledge it.
X+    * Code extracted from keyboard(). Keyboard() should call it instead. 
X+    */
X+ 
X+   int code;
X+   int val;
X+ 
X+   port_in(KEYBD, &code);	/* get the scan code for the key struck */
X+   port_in(PORT_B, &val);	/* strobe the keyboard to ack the char */
X+   port_out(PORT_B, val | KBIT);	/* strobe the bit high */
X+   port_out(PORT_B, val);	/* now strobe it low */
X+   return code;
X+ }
X+ #endif				/* DEBUGGER false - scan_keyboard() */
X+ 
X+ 
X+ /****************************************************************************/
X+ 
X+ 
X+ /* debugger hooks */
X+ 
X+ #ifdef DEBUGGER			/* CONSOLE <--> debugger glue routines */
X+ /*==========================================================================*
X+  *				kputc					    *
X+  *==========================================================================*/
X+ PUBLIC void kputc(c)
X+ int c;
X+ {
X+   out_char(&tty_struct[0], c);
X+ }
X+ 
X+ 
X+ typedef void (*pfv_t)();	/* helps broken compilers */
X+ PRIVATE pfv_t putc_func = kputc;  /* swapped when debugger is active */
X+ 
X+ 
X+ /*==========================================================================*
X+  *				putc					    *
X+  *==========================================================================*/
X+ PUBLIC void putc(c)
X+ int c;
X+ {
X+   /* Make putc() variable so dmp.c routines can be used by debugger. */
X+   (*putc_func)(c);
X+ }
X+ 
X+ 
X+ /* Db needs private tty variables since some hardware regs are write-only.
X+  * Use standard BIOS data area to communicate so db works on DOS too.
X+  */
X+ 
X+ #define BIOS_DATA_SEG 0x40	/* click */
X+ #define  ACTIVE_PAGE  0x62	/* offset to unsigned char */
X+ #define  ADDR_6845    0x63	/* offset to port_t (2 bytes) */
X+ #define  CRT_COLS     0x4A	/* offset to unsigned */
X+ #define  CRT_LEN      0x4C	/* offset to unsigned char */
X+ #define  CRT_MODE     0x49	/* offset to unsigned char */
X+ #define  CRT_MODE_SET 0x65	/* offset to unsigned char */
X+ #define  CRT_START    0x4E	/* offset to screenptr_t (2 bytes) */
X+ #define  CURSOR_MODE  0x60	/* offset to unsigned */
X+ #define  CRT_PALETTE  0x66	/* offset to unsigned char */
X+ #define  CURSOR_POSN  0x50	/* offset to screenptr_t [8] */
X+ 
X+ #define  KB_FLAG      0x17	/* offset to unsigned char */
X+ #define   CAPS_SH        6	/* shifts for some state bits */
X+ #define   NUM_SH	 5
X+ #define   SCROL_SH       4
X+ #define  KB_FLAG_1    0x18	/* offset to unsigned char */
X+ 
X+ 
X+ /*==========================================================================*
X+  *				get_kbd_state				    *
X+  *==========================================================================*/
X+ PUBLIC void get_kbd_state()
X+ {
X+   if ( vid_port != 0 )
X+     pokew( BIOS_DATA_SEG, KB_FLAG, (numlock<<NUM_SH) | (capslock<<CAPS_SH) );
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				get_scr_state				    *
X+  *==========================================================================*/
X+ PUBLIC void get_scr_state()
X+ {
X+   if ( vid_port != 0 )		/* console (just about) all initialized */
X+   {
X+     pokeb( BIOS_DATA_SEG, ACTIVE_PAGE, 0 );
X+     pokew( BIOS_DATA_SEG, ADDR_6845, vid_port );
X+     pokew( BIOS_DATA_SEG, CRT_COLS, LINE_WIDTH );
X+     pokeb( BIOS_DATA_SEG, CRT_MODE, color ? 3 : 7 );
X+     pokew( BIOS_DATA_SEG, CRT_START, tty_struct[0].tty_org );
X+     pokew( BIOS_DATA_SEG, CURSOR_MODE, CURSOR_SHAPE);
X+     pokew( BIOS_DATA_SEG, CURSOR_POSN + 0,
X+            tty_struct[0].tty_column | (tty_struct[0].tty_row << 8) );
X+   }
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				reset_kbd_state				    *
X+  *==========================================================================*/
X+ PUBLIC void reset_kbd_state()
X+ {
X+   control = alt = FALSE;
X+   if ( vid_port != 0 )
X+     set_leds();
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				set_db_putc				    *
X+  *==========================================================================*/
X+ PUBLIC void set_db_putc()
X+ {
X+   extern void outbyte();
X+ 
X+   putc_func = outbyte;
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				set_ker_putc				    *
X+  *==========================================================================*/
X+ PUBLIC void set_ker_putc()
X+ {
X+   putc_func = kputc;
X+ }
X+ #endif				/* DEBUGGER - glue routines */
END_OF_FILE
if test 7608 -ne `wc -c <'kerneldif/Bconsole.c.cdi'`; then
    echo shar: \"'kerneldif/Bconsole.c.cdi'\" unpacked with wrong size!
fi
# end of 'kerneldif/Bconsole.c.cdi'
fi
if test -f 'kerneldif/Brs232.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/Brs232.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/Brs232.c.cdif'\" \(314 characters\)
sed "s/^X//" >'kerneldif/Brs232.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3B/rs232.c	Sat Dec 31 05:43:21 1988
X--- kernel/rs232.c	Sat Mar 11 19:51:54 1989
X***************
X*** 669,671 ****
X--- 669,673 ----
X        rs->ostate ^= (ODONE | OQUEUED);	/* ODONE on, OQUEUED off */
X+       unlock();			/* safe, for complicated reasons */
X        tty_wakeup();
X+       lock();
X      }
END_OF_FILE
if test 314 -ne `wc -c <'kerneldif/Brs232.c.cdif'`; then
    echo shar: \"'kerneldif/Brs232.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/Brs232.c.cdif'
fi
echo shar: End of archive 2 \(of 10\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 3 - By Bruce Evans
Message-ID: <5265@ditmela.oz>
Date: 18 May 89 01:22:21 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1266


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 10)."
# Contents:  kerneldif/Btty.c.cdif kerneldif/at_wini.c.cdif
#   kerneldif/axmakefile.cdi kerneldif/clock.c.cdif
#   kerneldif/console.c.cdif kerneldif/const.h.cdif
#   kerneldif/tty.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:33:56 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/Btty.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/Btty.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/Btty.c.cdif'\" \(2878 characters\)
sed "s/^X//" >'kerneldif/Btty.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3B/tty.c	Mon Jan  2 02:55:53 1989
X--- kernel/tty.c	Thu Mar  9 21:23:34 1989
X***************
X*** 82,86 ****
X  PRIVATE unsigned reply_count;	/* counts tty_reply() calls */
X- PRIVATE unsigned tty_awake;	/* nonzero after wakeup till do_int() exits */
X  
X  
X  /*===========================================================================*
X--- 82,90 ----
X  PRIVATE unsigned reply_count;	/* counts tty_reply() calls */
X  
X+ /* Test-and-set flag, set during tty_wakeup().  Remains set if do_int() is
X+  * scheduled until do_int() is finished.
X+  */
X+ PRIVATE int tty_awake;
X  
X+ 
X  /*===========================================================================*
X***************
X*** 790,794 ****
X    mode = m_ptr->COUNT;
X!   if (mode & R_BIT && tp->tty_inleft != 0 && caller == tp->tty_inproc)
X  	/* Process was reading when killed.  Clean up input. */
X  	tty_icancel(tp);
X    if (mode & W_BIT && tp->tty_outleft != 0 && caller == tp->tty_outproc)
X--- 794,800 ----
X    mode = m_ptr->COUNT;
X!   if (mode & R_BIT && tp->tty_inleft != 0 && caller == tp->tty_inproc) {
X  	/* Process was reading when killed.  Clean up input. */
X  	tty_icancel(tp);
X+ 	tp->tty_inleft = 0;
X+   }
X    if (mode & W_BIT && tp->tty_outleft != 0 && caller == tp->tty_outproc)
X***************
X*** 817,819 ****
X    if ((status = send(replyee, &tty_mess)) != OK)
X! 	printf("\r\ntty_reply failed with status\r\n", status);
X    ++reply_count;
X--- 823,825 ----
X    if ((status = send(replyee, &tty_mess)) != OK)
X! 	printf("\r\ntty_reply failed with status %d\r\n", status);
X    ++reply_count;
X***************
X*** 993,995 ****
X    tp->tty_incount = 0;
X-   tp->tty_inleft = 0;
X    tp->tty_lfct = 0;
X--- 999,1000 ----
X***************
X*** 1091,1095 ****
X   * completions. The timeout smooths slow terminal input.
X   */
X  
X! #define WAKEUP_TIMEOUT (HZ/20)	/* adjust to taste, 1 for fast processor */
X  
X--- 1096,1104 ----
X   * completions. The timeout smooths slow terminal input.
X+  *
X+  * Wakeup_timeout and previous_events are probably deadwood (always use
X+  * timeout 1) but tty_awake is probably important to help avoid calling TTY
X+  * too often, apart from its locking function.
X   */
X  
X! #define WAKEUP_TIMEOUT (HZ/60)	/* adjust to taste, 1 for fast processor */
X  
X***************
X*** 1098,1106 ****
X  
X!   if (tty_events != 0 && !tty_awake) {
X  	if (tty_events >= EVENT_THRESHOLD || tty_events == previous_events ||
X  	    --wakeup_timeout == 0) {
X- 		interrupt(TTY, &wakeup_mess);
X- 		tty_awake = TRUE;
X  		wakeup_timeout = WAKEUP_TIMEOUT;
X  	}
X  	previous_events = tty_events;
X--- 1107,1116 ----
X  
X!   if (tty_events != 0 && !test_and_set(&tty_awake)) {
X  	if (tty_events >= EVENT_THRESHOLD || tty_events == previous_events ||
X  	    --wakeup_timeout == 0) {
X  		wakeup_timeout = WAKEUP_TIMEOUT;
X+ 		interrupt(TTY, &wakeup_mess);
X  	}
X+ 	else
X+ 		tty_awake = FALSE;
X  	previous_events = tty_events;
END_OF_FILE
if test 2878 -ne `wc -c <'kerneldif/Btty.c.cdif'`; then
    echo shar: \"'kerneldif/Btty.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/Btty.c.cdif'
fi
if test -f 'kerneldif/at_wini.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/at_wini.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/at_wini.c.cdif'\" \(4503 characters\)
sed "s/^X//" >'kerneldif/at_wini.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/at_wini.c	Thu Oct  6 21:07:07 1988
X--- kernel/at_wini.c	Thu Mar 23 04:46:45 1989
X***************
X*** 191,193 ****
X    phys_bytes usr_buf;
X!   register int i, old_state;
X    int r = 0;
X--- 191,193 ----
X    phys_bytes usr_buf;
X!   register int i;
X    int r = 0;
X***************
X*** 215,220 ****
X  		receive(HARDWARE, &w_mess);
X- /*		old_state = lock(); */
X- 		dma_read((unsigned)(usr_buf >> 4), (unsigned)(usr_buf & 0x0F));
X- /*		restore(old_state); */
X- 		usr_buf += 0x200;
X  		if (win_results() != OK) {
X--- 215,216 ----
X***************
X*** 223,224 ****
X--- 219,222 ----
X  		}
X+ 		port_read(WIN_REG1, usr_buf, (phys_bytes) SECTOR_SIZE);
X+ 		usr_buf += SECTOR_SIZE;
X  	}
X***************
X*** 233,238 ****
X  	for (i=0; i<BLOCK_SIZE/SECTOR_SIZE; i++) {
X! /*		old_state = lock(); */
X! 		dma_write((unsigned)(usr_buf >> 4), (unsigned)(usr_buf&0x0F));
X! /*		restore(old_state); */
X! 		usr_buf += 0x200;
X  		receive(HARDWARE, &w_mess);
X--- 231,234 ----
X  	for (i=0; i<BLOCK_SIZE/SECTOR_SIZE; i++) {
X! 		port_write(WIN_REG1, usr_buf, (phys_bytes) SECTOR_SIZE);
X! 		usr_buf += SECTOR_SIZE;
X  		receive(HARDWARE, &w_mess);
X***************
X*** 260,265 ****
X  
X!   int i, r, old_state;
X  
X    /* Strobe reset bit low. */
X-   old_state = lock();
X    port_out(WIN_REG9, 4);
X--- 256,260 ----
X  
X!   int i, r;
X  
X    /* Strobe reset bit low. */
X    port_out(WIN_REG9, 4);
X***************
X*** 268,270 ****
X    port_out(WIN_REG9, wini[0].wn_ctlbyte & 0x0F);
X-   restore(old_state);
X    for (i = 0; i < MAX_WIN_RETRY && drive_busy(); i++)
X--- 263,264 ----
X***************
X*** 344,348 ****
X  /*============================================================================*
X!  *				win_results				      *
X   *============================================================================*/
X! PRIVATE win_results()
X  {
X--- 338,342 ----
X  /*============================================================================*
X!  *				old_win_results				      *
X   *============================================================================*/
X! PRIVATE old_win_results()
X  {
X***************
X*** 388,390 ****
X  
X! 	register int i, old_state;
X  	int r;
X--- 382,384 ----
X  
X! 	register int i;
X  	int r;
X***************
X*** 396,398 ****
X  	r = WIN_REG2;
X- 	old_state = lock();
X  	port_out(WIN_REG9, command[0]);
X--- 390,391 ----
X***************
X*** 400,402 ****
X  		port_out(r, command[i]);
X- 	restore(old_state);
X  	return(OK);
X--- 393,394 ----
X***************
X*** 422,425 ****
X    /* Calculate the address off the parameters and copy them to buf */
X!   address = ((long)segment << 4) + offset;
X!   phys_copy(address, umap(proc_addr(WINCHESTER), D, (vir_bytes)buf, 16), 16L);
X  
X--- 414,417 ----
X    /* Calculate the address off the parameters and copy them to buf */
X!   address = ((long)segment << HCLICK_SHIFT) + offset;
X!   phys_copy(address, umap(cproc_addr(WINCHESTER), D, (vir_bytes)buf, 16), 16L);
X  
X***************
X*** 433,436 ****
X    /* Calculate the address off the parameters and copy them to buf */
X!   address = ((long)segment << 4) + offset;
X!   phys_copy(address, umap(proc_addr(WINCHESTER), D, (vir_bytes)buf, 16), 16L);
X  
X--- 425,428 ----
X    /* Calculate the address off the parameters and copy them to buf */
X!   address = ((long)segment << HCLICK_SHIFT) + offset;
X!   phys_copy(address, umap(cproc_addr(WINCHESTER), D, (vir_bytes)buf, 16), 16L);
X  
X***************
X*** 440,442 ****
X    /* Get the nummer of drives from the bios */
X!   phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, (vir_bytes)buf, 1), 1L);
X    nr_drives = (int) *buf;
X--- 432,434 ----
X    /* Get the nummer of drives from the bios */
X!   phys_copy(0x475L, umap(cproc_addr(WINCHESTER), D, (vir_bytes)buf, 1), 1L);
X    nr_drives = (int) *buf;
X***************
X*** 516,517 ****
X--- 508,510 ----
X  	wn->wn_low = *(long *)&buf[offset];
X+ #ifdef STUPID_WINI_ADJUST
X  	if ((wn->wn_low % (BLOCK_SIZE/SECTOR_SIZE)) != 0) {
X***************
X*** 521,522 ****
X--- 514,516 ----
X  	}
X+ #endif
X  	wn->wn_size = *(long *)&buf[offset + sizeof(long)] - adjust;
X***************
X*** 549,550 ****
X--- 543,561 ----
X  		;
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				win_results				    *
X+  *==========================================================================*/
X+ PRIVATE int win_results()
X+ {
X+ /* Extract results from the controller after an operation, then reenable the
X+  * (slave) interrupt controller.
X+  */
X+ 
X+   int r;
X+ 
X+   r = old_win_results();
X+   cim_at_wini();
X+   return(r);
X  }
END_OF_FILE
if test 4503 -ne `wc -c <'kerneldif/at_wini.c.cdif'`; then
    echo shar: \"'kerneldif/at_wini.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/at_wini.c.cdif'
fi
if test -f 'kerneldif/axmakefile.cdi' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/axmakefile.cdi'\"
else
echo shar: Extracting \"'kerneldif/axmakefile.cdi'\" \(8507 characters\)
sed "s/^X//" >'kerneldif/axmakefile.cdi' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/axmakefile	Sat Mar 25 19:57:24 1989
X***************
X*** 0 ****
X--- 1,303 ----
X+ # Say 'make at' to make a kernel with the AT winchester driver.
X+ # Say 'make xt' to make a kernel with the XT winchester driver.
X+ # Say 'make' to make the default kernel.
X+ # Use the at kernel if you don't have a hard disk.
X+ 
X+ # Uncomment one of these 4 groups of defines for special kernels.
X+ # Protected mode may be defined for 8088 through 80386 processors, but only
X+ # 286's and 386's take advantage of it.
X+ # The posted version doesn't support DEBUGanything, PM3, or anything386.
X+ 
X+ # Protected mode.
X+  CPU		= -Di8088 -Di80286 # -Di80386
X+  SPECOBJS	= $(PM2OBJS) # $(PM3OBJS)
X+ 
X+ # Debugger and protected mode.
X+ # DEBUG_EARLY	= -DDEBUG_EARLY
X+ # DEBUGGER	= -DDEBUGGER
X+ # CPU		= -Di8088 -Di80286 # -Di80386
X+ # SPECOBJS	= $(DBOBJS) $(DB_PM2OBJS) $(PM2OBJS) #$(DB_PM3OBJS) $(PM3OBJS)
X+ 
X+ # Debugger.
X+ # DEBUG_EARLY	= -DDEBUG_EARLY
X+ # DEBUGGER	= -DDEBUGGER
X+ # CPU		= i8088
X+ # SPECOBJS	= $(DBOBJS)
X+ 
X+ # Ordinary kernel (1.3 with a few improvements).
X+ # CPU		= -Di8088
X+ 
X+ # Futher, uncomment one of these 3 groups of defines to select the TTY driver.
X+ 
X+ # 1.3 TTY driver.
X+  C_RS232	= -DC_RS232_INT_HANDLERS
X+  OLD_TTY	= -DOLD_TTY
X+ 
X+ # Bruce's TTY driver.
X+ # RS2 		= rs2.o
X+ 
X+ # Bruce's TTY driver, but use the C interrupt handlers.
X+ # C_RS232	= -DC_RS232_INT_HANDLERS
X+ 
X+ # Further, uncomment one of these 2 groups of defines to select the
X+ # environment.
X+ 
X+ # Standard Minix.
X+ # CFLAGS include the following nonstandard ones.
X+ # -F:	run cpp and cem sequentially (used when memory is tight)
X+ # -T.:	put temporaries in working directory (when RAM disk is small)
X+  ASLD		= -DASLD
X+  BIN		= .
X+  CC		= cc
X+  CFLAGS		= $(CPPFLAGS) -F -T.
X+  END		= /usr/lib/end.s
X+  LD		= asld
X+  LIBS		= /usr/lib/libc.a
X+  o		= s
X+ 
X+ # Bruce's Minix.
X+ # BIN		= /etc/system
X+ # CC		= ecc
X+ # CFLAGS		= $(CPPFLAGS)
X+ # LD		= ld
X+ # LIBS		= /local/lib/libc.a
X+ # o		= o
X+ # .s.o:
X+ #	$(CC) -c $*.s
X+ # VOID		= -Dvoid=int
X+ 
X+ # Other defines for C.
X+ # AM_KERNEL	= -DAM_KERNEL	# Amoeba kernel (doesn't work)
X+  AUTO_BIOS	= -DAUTO_BIOS=0	# for xt_wini.c, make it =1 if wanted
X+ # LINEWRAP	= -DLINEWRAP	# wrap lines at column 80
X+ # NO_HANDSHAKE	= -DNO_HANDSHAKE	# no hardware handshake for RS232
X+ # SPARE_VIDEO	= -DSPARE_VIDEO_MEMORY	# put mem from any 2nd vid card in map
X+  STUPID_WINI	= -DSTUPID_WINI_ADJUST	# skip odd 1st sector of partition
X+ 
X+ # Other defines for make.
X+ CPP		= /lib/cpp
X+ CPPFLAGS	= $(ASLD) $(AUTO_BIOS) $(AM_KERNEL) $(CPU) $(C_RS232) \
X+ 		  $(DEBUG_EARLY) $(DEBUGGER) $(LINEWRAP) $(NO_HANDSHAKE) \
X+ 		  $(OLD_TTY) $(SPARE_VIDEO) $(STUPID_WINI) $(VOID)
X+ LDFLAGS		= -i
X+ START		= mpx88.$o
X+ h		= ../h
X+ 
X+ DB_PM2OBJS	= db286.$o
X+ DB_PM3OBJS	= db386.$o
X+ DBOBJS		= db/int88.$o db/db.$o db/getline.$o db/io.$o db/keyboard.$o \
X+ 		  db/lib88.$o db/pcio.$o db/sym.$o db/unasm.$o
X+ KEROBJS		= main.$o tty.$o floppy.$o system.$o proc.$o clock.$o \
X+ 		  memory.$o console.$o rs232.$o $(RS2) printer.$o table.$o \
X+ 		  klib88.$o dmp.$o \
X+ 		  exception.$o i8259.$o misc.$o
X+ PM2OBJS		= mpx286.$o klib286.$o protect.$o 
X+ PM3OBJS		= mpx386.$o klib386.$o
X+ SOBJS		= db286.s db386.s klib286.s klib386.s klib88.s \
X+ 		  mpx286.s mpx386.s mpx88.s rs2.s
X+ 
X+ ATWINI		= at_wini.$o
X+ XTWINI		= xt_wini.$o
X+ 
X+ # Main thing to make.  Swap the order of these if you prefer and XT kernel.
X+ 
X+ at: $(START) $(KEROBJS) $(SPECOBJS) $(ATWINI) $(LIBS) $(END)
X+ 	$(LD) $(LDFLAGS) -o $(BIN)/atkernel \
X+     $(START) $(SPECOBJS) $(KEROBJS) $(ATWINI) $(LIBS) $(END) \
X+ #   -s > atkernel.sym
X+ #	ast -X $(BIN)/atkernel atkernel.sym
X+ 	rm -f $(BIN)/kernel
X+ 	ln $(BIN)/atkernel $(BIN)/kernel
X+ 
X+ xt: $(START) $(KEROBJS) $(SPECOBJS) $(XTWINI) $(LIBS) $(END)
X+ 	$(LD) $(LDFLAGS) -o $(BIN)/xtkernel \
X+     $(START) $(KEROBJS) $(SPECOBJS) $(XTWINI) $(LIBS) $(END) \
X+ #   -s > xtkernel.sym
X+ #	ast -X $(BIN)/xtkernel xtkernel.sym
X+ 	rm -f $(BIN)/kernel
X+ 	ln $(BIN)/xtkernel $(BIN)/kernel
X+ 
X+ clean:
X+ 	rm -f $(START) $(DB_PM2OBJS) $(DB_PM3OBJS) $(KEROBJS) \
X+ 	      $(PM2OBJS) $(PM3OBJS) $(SOBJS) \
X+ 	      $(ATWINI) $(XTWINI
X+ 
X+ db286.o: db286.s
X+ 	$(CC) -c $*.s
X+ db286.s: $h/const.h const.h protect.h sconst.h sglo.h db286.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ db386.o: db386.s
X+ 	$(CC) -c $*.s
X+ db386.s: $h/const.h const.h protect.h sconst.h sglo.h db386.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ klib286.o: klib286.s
X+ 	$(CC) -c $*.s
X+ klib286.s: $h/const.h const.h protect.h sconst.h sglo.h klib286.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ klib386.o: klib386.s
X+ 	$(CC) -c $*.s
X+ klib386.s: $h/const.h const.h protect.h sconst.h sglo.h klib386.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ klib88.o: klib88.s
X+ 	$(CC) -c $*.s
X+ klib88.s: $h/const.h const.h sconst.h sglo.h klib88.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ mpx286.o: mpx286.s
X+ 	$(CC) -c $*.s
X+ mpx286.s: const.h protect.h sconst.h sglo.h mpx286.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ mpx386.o: mpx386.s
X+ 	$(CC) -c $*.s
X+ mpx386.s: const.h protect.h sconst.h sglo.h mpx386.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ mpx88.o: mpx88.s
X+ 	$(CC) -c $*.s
X+ mpx88.s: $h/const.h $h/com.h const.h sconst.h sglo.h mpx88.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ rs2.o: rs2.s
X+ 	$(CC) -c $*.s
X+ rs2.s: $h/const.h const.h sconst.h sglo.h rs2.x
X+ 	$(CPP) $(CPPFLAGS) $*.x | grep -v '^\#' > $*.s
X+ 
X+ clock.$o:	const.h type.h $h/const.h $h/type.h
X+ clock.$o:	$h/callnr.h
X+ clock.$o:	$h/com.h
X+ clock.$o:	$h/error.h
X+ clock.$o:	$h/signal.h
X+ clock.$o:	glo.h
X+ clock.$o:	proc.h
X+ 
X+ console.$o:	const.h type.h $h/const.h $h/type.h
X+ console.$o:	$h/callnr.h
X+ console.$o:	$h/com.h
X+ console.$o:	$h/error.h
X+ console.$o:	$h/sgtty.h
X+ console.$o:	$h/signal.h
X+ console.$o:	glo.h
X+ console.$o:	proc.h
X+ console.$o:	protect.h
X+ console.$o:	tty.h
X+ 
X+ floppy.$o:	const.h type.h $h/const.h $h/type.h
X+ floppy.$o:	$h/callnr.h
X+ floppy.$o:	$h/com.h
X+ floppy.$o:	$h/error.h
X+ floppy.$o:	glo.h
X+ floppy.$o:	proc.h
X+ 
X+ dmp.$o:		const.h type.h $h/const.h $h/type.h
X+ dmp.$o:		$h/callnr.h
X+ dmp.$o:		$h/com.h
X+ dmp.$o:		$h/error.h
X+ dmp.$o:		glo.h
X+ dmp.$o:		proc.h
X+ 
X+ main.$o:	const.h type.h $h/const.h $h/type.h
X+ main.$o:	$h/boot.h
X+ main.$o:	$h/callnr.h
X+ main.$o:	$h/com.h
X+ main.$o:	$h/error.h
X+ main.$o:	$h/signal.h
X+ main.$o:	glo.h
X+ main.$o:	proc.h
X+ 
X+ memory.$o:	const.h type.h $h/const.h $h/type.h
X+ memory.$o:	$h/callnr.h
X+ memory.$o:	$h/com.h
X+ memory.$o:	$h/error.h
X+ memory.$o:	glo.h
X+ memory.$o:	proc.h
X+ 
X+ printer.$o:	const.h type.h $h/const.h $h/type.h
X+ printer.$o:	$h/callnr.h
X+ printer.$o:	$h/com.h
X+ printer.$o:	$h/error.h
X+ printer.$o:	proc.h
X+ printer.$o:	glo.h
X+ 
X+ proc.$o:	const.h type.h $h/const.h $h/type.h
X+ proc.$o:	$h/callnr.h
X+ proc.$o:	$h/com.h
X+ proc.$o:	$h/error.h
X+ proc.$o:	glo.h
X+ proc.$o:	proc.h
X+ 
X+ rs232.$o:	const.h $h/const.h $h/type.h
X+ rs232.$o:	$h/sgtty.h
X+ rs232.$o:	tty.h
X+ 
X+ system.$o:	const.h type.h $h/const.h $h/type.h
X+ system.$o:	$h/boot.h
X+ system.$o:	$h/callnr.h
X+ system.$o:	$h/com.h
X+ system.$o:	$h/error.h
X+ system.$o:	$h/signal.h
X+ system.$o:	glo.h
X+ system.$o:	proc.h
X+ system.$o:	protect.h
X+ 
X+ table.$o:	const.h type.h $h/const.h $h/type.h $h/com.h
X+ table.$o:	glo.h
X+ table.$o:	proc.h
X+ table.$o:	tty.h
X+ 
X+ tty.$o:		const.h type.h $h/const.h $h/type.h
X+ tty.$o:		$h/callnr.h
X+ tty.$o:		$h/com.h
X+ tty.$o:		$h/error.h
X+ tty.$o:		$h/sgtty.h
X+ tty.$o:		$h/signal.h
X+ tty.$o:		glo.h
X+ tty.$o:		proc.h
X+ tty.$o:		tty.h
X+ tty.$o:		ttymaps.h
X+ 
X+ at_wini.$o:	const.h type.h $h/const.h $h/type.h
X+ at_wini.$o:	$h/callnr.h
X+ at_wini.$o:	$h/com.h
X+ at_wini.$o:	$h/error.h
X+ at_wini.$o:	proc.h
X+ 
X+ xt_wini.$o:	const.h type.h $h/const.h $h/type.h
X+ xt_wini.$o:	$h/callnr.h
X+ xt_wini.$o:	$h/com.h
X+ xt_wini.$o:	$h/error.h
X+ xt_wini.$o:	proc.h
X+ 
X+ exception.$o:	$h/const.h
X+ exception.$o:	$h/type.h
X+ exception.$o:	$h/signal.h
X+ exception.$o:	const.h
X+ exception.$o:	type.h
X+ exception.$o:	glo.h
X+ exception.$o:	proc.h
X+ 
X+ i8259.$o:	$h/const.h
X+ i8259.$o:	$h/type.h
X+ i8259.$o:	$h/com.h
X+ i8259.$o:	const.h
X+ i8259.$o:	type.h
X+ i8259.$o:	glo.h
X+ i8259.$o:	proc.h
X+ 
X+ misc.$o:	$h/const.h
X+ misc.$o:	$h/type.h
X+ misc.$o:	const.h
X+ misc.$o:	type.h
X+ misc.$o:	glo.h
X+ 
X+ protect.$o:	$h/const.h
X+ protect.$o:	$h/type.h
X+ protect.$o:	const.h
X+ protect.$o:	type.h
X+ protect.$o:	glo.h
X+ protect.$o:	proc.h
X+ protect.$o:	protect.h
END_OF_FILE
if test 8507 -ne `wc -c <'kerneldif/axmakefile.cdi'`; then
    echo shar: \"'kerneldif/axmakefile.cdi'\" unpacked with wrong size!
fi
# end of 'kerneldif/axmakefile.cdi'
fi
if test -f 'kerneldif/clock.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/clock.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/clock.c.cdif'\" \(10602 characters\)
sed "s/^X//" >'kerneldif/clock.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/clock.c	Thu Oct 20 13:14:50 1988
X--- kernel/clock.c	Thu Mar 23 00:16:07 1989
X***************
X*** 3,5 ****
X   *
X!  *   CLOCK_TICK:  a clock interrupt has occurred
X   *   GET_TIME:    a process wants the real time
X--- 3,5 ----
X   *
X!  *   HARD_INT:    a clock interrupt has occurred
X   *   GET_TIME:    a process wants the real time
X***************
X*** 14,16 ****
X   * |------------+----------+---------+---------|
X!  * | CLOCK_TICK |          |         |         |
X   * |------------+----------+---------+---------|
X--- 14,16 ----
X   * |------------+----------+---------+---------|
X!  * | HARD_INT   |          |         |         |
X   * |------------+----------+---------+---------|
X***************
X*** 41,43 ****
X  #define SCHED_RATE (MILLISEC*HZ/1000)	/* number of ticks per schedule */
X- #define FLUSH_MASK        07	/* bit mask used for flushing RS232 input */
X  
X--- 41,42 ----
X***************
X*** 47,48 ****
X--- 46,48 ----
X  #define IBM_FREQ    1193182L	/* IBM clock frequency for setting timer */
X+ #define TIMER_COUNT (unsigned) (IBM_FREQ/HZ)/* count to load into timer */
X  #define SQUARE_WAVE     0x36	/* mode for generating square wave */
X***************
X*** 52,53 ****
X--- 52,55 ----
X  PRIVATE real_time next_alarm;	/* probable time of next alarm */
X+ PRIVATE real_time pending_ticks;	/* ticks seen by low level only */
X+ PRIVATE real_time realtime;	/* real time clock */
X  PRIVATE int sched_ticks = SCHED_RATE;	/* counter: when 0, call scheduler */
X***************
X*** 56,58 ****
X  PRIVATE int (*watch_dog[NR_TASKS+1])();	/* watch_dog functions to call */
X- extern int flush_flag;		/* tells clock when to flush the tty buf */
X  
X--- 58,59 ----
X***************
X*** 76,77 ****
X--- 77,83 ----
X  
X+      lock();
X+      realtime += pending_ticks;	/* transfer ticks from low level handler */
X+      pending_ticks = 0;
X+      unlock();
X+ 
X       switch (opcode) {
X***************
X*** 80,82 ****
X  	case SET_TIME:	 do_set_time(&mc);	break;
X! 	case CLOCK_TICK: do_clocktick();	break;
X  	default: panic("clock task got bad message", mc.m_type);
X--- 86,88 ----
X  	case SET_TIME:	 do_set_time(&mc);	break;
X! 	case HARD_INT:   do_clocktick();	break;
X  	default: panic("clock task got bad message", mc.m_type);
X***************
X*** 86,88 ****
X      mc.m_type = OK;
X!     if (opcode != CLOCK_TICK) send(mc.m_source, &mc);
X    }
X--- 92,94 ----
X      mc.m_type = OK;
X!     if (opcode != HARD_INT) send(mc.m_source, &mc);
X    }
X***************
X*** 114,116 ****
X    rp->p_alarm = (delta_ticks == 0L ? 0L : realtime + delta_ticks);
X!   if (proc_nr < 0) watch_dog[-proc_nr] = function;
X  
X--- 120,122 ----
X    rp->p_alarm = (delta_ticks == 0L ? 0L : realtime + delta_ticks);
X!   if istaskp(rp) watch_dog[-proc_nr] = function;
X  
X***************
X*** 118,120 ****
X    next_alarm = MAX_P_LONG;
X!   for (rp = &proc[0]; rp < &proc[NR_TASKS+NR_PROCS]; rp++)
X  	if(rp->p_alarm != 0 && rp->p_alarm < next_alarm)next_alarm=rp->p_alarm;
X--- 124,126 ----
X    next_alarm = MAX_P_LONG;
X!   for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++)
X  	if(rp->p_alarm != 0 && rp->p_alarm < next_alarm)next_alarm=rp->p_alarm;
X***************
X*** 153,155 ****
X  {
X! /* This routine is called on every clock tick. */
X  
X--- 159,161 ----
X  {
X! /* This routine called on clock ticks when a lot of work needs to be done. */
X  
X***************
X*** 157,167 ****
X    register int t, proc_nr;
X-   extern int pr_busy, pcount, cum_count, prev_ct;
X  
X-   /* To guard against race conditions, first copy 'lost_ticks' to a local
X-    * variable, add this to 'realtime', and then subtract it from 'lost_ticks'.
X-    */
X-   t = lost_ticks;		/* 'lost_ticks' counts missed interrupts */
X-   realtime += t + 1;		/* update the time of day */
X-   lost_ticks -= t;		/* these interrupts are no longer missed */
X- 
X    if (next_alarm <= realtime) {
X--- 163,165 ----
X***************
X*** 169,171 ****
X  	next_alarm = MAX_P_LONG;	/* start computing next alarm */
X! 	for (rp = &proc[0]; rp < &proc[NR_TASKS+NR_PROCS]; rp++) {
X  		if (rp->p_alarm != (real_time) 0) {
X--- 167,169 ----
X  	next_alarm = MAX_P_LONG;	/* start computing next alarm */
X! 	for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
X  		if (rp->p_alarm != (real_time) 0) {
X***************
X*** 177,180 ****
X  				 */
X! 				proc_nr = rp - proc - NR_TASKS;
X! 				if (proc_nr >= 0)
X  					cause_sig(proc_nr, SIGALRM);
X--- 175,177 ----
X  				 */
X! 				if ( (proc_nr = proc_number(rp)) >= 0)
X  					cause_sig(proc_nr, SIGALRM);
X***************
X*** 192,210 ****
X  
X-   accounting();			/* keep track of who is using the cpu */
X- 
X-   /* If input characters are accumulating on an RS232 line, process them. */
X-   if (flush_flag) {
X- 	t = (int) realtime;		/* only low-order bits matter */
X- 	if ( (t & FLUSH_MASK) == 0) rs_flush();	/* flush tty input */
X-   }
X- 
X    /* If a user process has been running too long, pick another one. */
X    if (--sched_ticks == 0) {
X! 	if (bill_ptr == prev_ptr) sched();	/* process has run too long */
X  	sched_ticks = SCHED_RATE;		/* reset quantum */
X  	prev_ptr = bill_ptr;			/* new previous process */
X- 
X- 	/* Check if printer is hung up, and if so, restart it. */
X- 	if (pr_busy && pcount > 0 && cum_count == prev_ct) pr_char(); 
X- 	prev_ct = cum_count;	/* record # characters printed so far */
X    }
X--- 189,195 ----
X  
X    /* If a user process has been running too long, pick another one. */
X    if (--sched_ticks == 0) {
X! 	if (bill_ptr == prev_ptr) locksched();	/* process has run too long */
X  	sched_ticks = SCHED_RATE;		/* reset quantum */
X  	prev_ptr = bill_ptr;			/* new previous process */
X    }
X***************
X*** 217,239 ****
X   *===========================================================================*/
X! PRIVATE accounting()
X! {
X! /*
X!  * Update user and system accounting times.  Charge the current process for 
X!  * user time or system time.  In addition, if the current proces (i.e.
X!  * prev_proc, because cur_proc is always CLOCK) is a task, charge it too.
X!  * This is just for the F1 display.
X!  */
X  
X-   register struct proc *rp;
X  
X-   if (prev_proc >= LOW_USER) {
X- 	bill_ptr->user_time++;				/* user time */
X-   } else {
X- 	bill_ptr->sys_time++;				/* system time */
X- 	rp = proc_addr(prev_proc);
X- 	if (prev_proc != IDLE) rp->sys_time++;
X-   }
X- }
X- 
X- 
X  #ifdef i8088
X--- 202,206 ----
X   *===========================================================================*/
X! /* This is now done at the lowest level, in clock_handler(). */
X  
X  
X  #ifdef i8088
X***************
X*** 246,256 ****
X  
X-   unsigned int count, low_byte, high_byte;
X- 
X-   count = (unsigned) (IBM_FREQ/HZ);	/* value to load into the timer */
X-   low_byte = count & BYTE;		/* compute low-order byte */
X-   high_byte = (count >> 8) & BYTE;	/* compute high-order byte */
X    port_out(TIMER_MODE, SQUARE_WAVE);	/* set timer to run continuously */
X!   port_out(TIMER0, low_byte);		/* load timer low byte */
X!   port_out(TIMER0, high_byte);		/* load timer high byte */
X  }
X  #endif
X--- 213,301 ----
X  
X    port_out(TIMER_MODE, SQUARE_WAVE);	/* set timer to run continuously */
X!   port_out(TIMER0, TIMER_COUNT);	/* load timer low byte */
X!   port_out(TIMER0, TIMER_COUNT >> 8);	/* load timer high byte */
X  }
X  #endif
X+ 
X+ 
X+ /*===========================================================================*
X+  *				clock_handler				     *
X+  *===========================================================================*/
X+ PUBLIC clock_handler()
X+ {
X+ /* Switch context to do_clocktick if an alarm has gone off.
X+  * Also switch there to reschedule if the reschedule will do something.
X+  * This happens when
X+  *	(1) quantum has expired
X+  *	(2) current process received full quantum (as clock sampled it!)
X+  *	(3) something else is ready to run.
X+  * Also call TTY and PRINTER and let them do whatever is necessary.
X+  *
X+  * Many global global and static variables are accessed here.  The safety
X+  * of this must be justified.  Most of them are not changed here:
X+  *	k_reenter:
X+  *		This safely tells if the clock interrupt is nested.
X+  *	proc_ptr, bill_ptr:
X+  *		These are used for accounting.  It does not matter if proc.c
X+  *		is changing them, provided they are always valid pointers,
X+  *		since at worst the previous process would be billed.
X+  *	next_alarm, realtime, sched_ticks, bill_ptr, prev_ptr,
X+  *	rdy_head[USER_Q]:
X+  *		These are tested to decide whether to call interrupt().  It
X+  *		does not matter if the test is sometimes (rarely) backwards
X+  *		due to a race, since this will only delay the high-level
X+  *		processing by one tick, or call the high level unnecessarily.
X+  * The variables which are changed require more care:
X+  *	rp->user_time, rp->sys_time:
X+  *		These are protected by explicit locks in system.c.  They are
X+  *		not properly protected in dmp.c (the increment here is not
X+  *		atomic) but that hardly matters.
X+  *	pending_ticks:
X+  *		This is protected by an explicit lock in clock.c.  Don't
X+  *		update realtime directly, since there are too many
X+  *		references to it to guard conveniently.
X+  *	sched_ticks, prev_ptr:
X+  *		Updating these competes with similar code in do_clocktick().
X+  *		No lock is necessary, because if bad things happen here
X+  *		(like sched_ticks going negative), the code in do_clocktick()
X+  *		will restore the variables to reasonable values, and an
X+  *		occasional missed or extra sched() is harmless.
X+  *
X+  * Are these complications worth the trouble?  Well, they make the system 15%
X+  * faster on a 5MHz 8088, and make task debugging much easier since there are
X+  * no task switches on an inactive system.
X+  */
X+ 
X+   register struct proc *rp;
X+ 
X+   /* Update user and system accounting times.
X+    * First charge the current process for user time.
X+    * If the current process is not the billable process (usually because it
X+    * is a task), charge the billable process for system time as well.
X+    * Thus the unbillable tasks' user time is the billable users' system time.
X+    */
X+   if (k_reenter != 0)
X+ 	rp = cproc_addr(HARDWARE);
X+   else
X+ 	rp = proc_ptr;
X+   ++rp->user_time;
X+   if (rp != bill_ptr)
X+ 	++bill_ptr->sys_time;
X+ 
X+   ++pending_ticks;
X+   tty_wakeup();			/* possibly wake up TTY */
X+   pr_restart();			/* possibly restart printer */
X+ 
X+   if (next_alarm <= realtime + pending_ticks ||
X+       sched_ticks == 1 &&
X+       bill_ptr == prev_ptr && rdy_head[USER_Q] != NIL_PROC) {
X+ 	interrupt(CLOCK);
X+ 	return;
X+   }
X+ 
X+   if (--sched_ticks == 0) {
X+ 	/* If bill_ptr == prev_ptr, no ready users so don't need sched(). */
X+ 	sched_ticks = SCHED_RATE;	/* reset quantum */
X+ 	prev_ptr = bill_ptr;		/* new previous process */
X+   }
X+ }
END_OF_FILE
if test 10602 -ne `wc -c <'kerneldif/clock.c.cdif'`; then
    echo shar: \"'kerneldif/clock.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/clock.c.cdif'
fi
if test -f 'kerneldif/console.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/console.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/console.c.cdif'\" \(3676 characters\)
sed "s/^X//" >'kerneldif/console.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/console.c	Thu Oct 20 06:04:19 1988
X--- kernel/console.c	Sun Mar 12 00:34:42 1989
X***************
X*** 13,14 ****
X--- 13,15 ----
X  #include "proc.h"
X+ #include "protect.h"
X  #include "tty.h"
X***************
X*** 20,23 ****
X  /* Definitions used by the console driver. */
X- #define COLOR_BASE    0xB800	/* video ram paragraph for color display */
X- #define MONO_BASE     0xB000	/* video ram address for mono display */
X  #define C_VID_MASK    0x3FFF	/* mask for 16K video RAM */
X--- 21,22 ----
X***************
X*** 153,154 ****
X--- 152,154 ----
X     */
X+   lock();			/* the buffer is shared with RS232 */
X    if ( (k = tty_buf_count(tty_driver_buf)) < tty_buf_max(tty_driver_buf)) {
X***************
X*** 159,160 ****
X--- 159,161 ----
X  	tty_buf_count(tty_driver_buf)++;		/* increment counter */
X+ 	unlock();
X  
X***************
X*** 166,167 ****
X--- 167,169 ----
X  	/* Too many characters have been buffered.  Discard excess. */
X+ 	unlock();
X  	port_out(INT_CTL, ENABLE);	/* re-enable 8259A controller */
X***************
X*** 182,191 ****
X  
X-   extern char get_byte();
X    int count;
X    char c;
X!   unsigned segment, offset, offset1;
X  
X    /* Loop over the user bytes one at a time, outputting each one. */
X!   segment = (tp->tty_phys >> 4) & WORD_MASK;
X!   offset = tp->tty_phys & OFF_MASK;
X    offset1 = offset;
X--- 184,191 ----
X  
X    int count;
X    char c;
X!   unsigned long offset, offset1;
X  
X    /* Loop over the user bytes one at a time, outputting each one. */
X!   offset = tp->tty_phys;
X    offset1 = offset;
X***************
X*** 194,196 ****
X    while (tp->tty_outleft > 0 && tp->tty_inhibited == RUNNING) {
X! 	c = get_byte(segment, offset);	/* fetch 1 byte from user space */
X  	out_char(tp, c);	/* write 1 byte to terminal */
X--- 194,196 ----
X    while (tp->tty_outleft > 0 && tp->tty_inhibited == RUNNING) {
X! 	c = get_phys_byte(offset);	/* fetch 1 byte from user space */
X  	out_char(tp, c);	/* write 1 byte to terminal */
X***************
X*** 887,889 ****
X    if (color) {
X! 	vid_base = COLOR_BASE;
X  	vid_mask = C_VID_MASK;
X--- 887,889 ----
X    if (color) {
X! 	vid_base = COLOR_BASE >> HCLICK_SHIFT;
X  	vid_mask = C_VID_MASK;
X***************
X*** 892,894 ****
X    } else {
X! 	vid_base = MONO_BASE;
X  	vid_mask = M_VID_MASK;
X--- 892,894 ----
X    } else {
X! 	vid_base = MONO_BASE >> HCLICK_SHIFT;
X  	vid_mask = M_VID_MASK;
X***************
X*** 898,899 ****
X--- 898,904 ----
X  
X+ #ifdef i80286
X+   if (processor >= 286)
X+ 	vid_base = color ? COLOR_SELECTOR : MONO_SELECTOR;
X+ #endif
X+ 
X    if (ega) {
X***************
X*** 924,927 ****
X    }
X- }
X  
X  /*===========================================================================*
X--- 929,934 ----
X    }
X  
X+   enable_irq(KEYBOARD_IRQ);	/* safe now everything initialised! */
X+ }
X+ 
X  /*===========================================================================*
X***************
X*** 1021 ****
X--- 1028,1050 ----
X  }
X+ 
X+ 
X+ #ifndef DEBUGGER		/* debugger already has it */
X+ /*==========================================================================*
X+  *				scan_keyboard				    *
X+  *==========================================================================*/
X+ PUBLIC int scan_keyboard()
X+ {
X+   /* Fetch the character from the keyboard hardware and acknowledge it.
X+    * Code extracted from keyboard(). Keyboard() should call it instead. 
X+    */
X+ 
X+   int code;
X+   int val;
X+ 
X+   port_in(KEYBD, &code);	/* get the scan code for the key struck */
X+   port_in(PORT_B, &val);	/* strobe the keyboard to ack the char */
X+   port_out(PORT_B, val | KBIT);	/* strobe the bit high */
X+   port_out(PORT_B, val);	/* now strobe it low */
X+   return code;
X+ }
X+ #endif				/* DEBUGGER false - scan_keyboard() */
END_OF_FILE
if test 3676 -ne `wc -c <'kerneldif/console.c.cdif'`; then
    echo shar: \"'kerneldif/console.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/console.c.cdif'
fi
if test -f 'kerneldif/const.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/const.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/const.h.cdif'\" \(7031 characters\)
sed "s/^X//" >'kerneldif/const.h.cdif' <<'END_OF_FILE'
X*** kernel-1.3/const.h	Thu Oct  6 21:07:12 1988
X--- kernel/const.h	Thu Mar 23 03:19:08 1989
X***************
X*** 3,49 ****
X  #ifdef i8088
X- /* p_reg contains: ax, bx, cx, dx, si, di, bp, es, ds, cs, ss in that order. */
X- #define NR_REGS           11	/* number of general regs in each proc slot */
X- #define INIT_PSW      0x0200	/* initial psw */
X- #define INIT_SP (int*)0x0010	/* initial sp: 3 words pushed by kernel */
X  
X! /* The following values are used in the assembly code.  Do not change the
X!  * values of 'ES_REG', 'DS_REG', 'CS_REG', or 'SS_REG' without making the 
X!  * corresponding changes in the assembly code.
X   */
X! #define ES_REG             7	/* proc[i].p_reg[ESREG] is saved es */
X! #define DS_REG             8	/* proc[i].p_reg[DSREG] is saved ds */
X! #define CS_REG             9	/* proc[i].p_reg[CSREG] is saved cs */
X! #define SS_REG            10	/* proc[i].p_reg[SSREG] is saved ss */
X  
X! #define VECTOR_BYTES     284	/* bytes of interrupt vectors to save */
X! #define MEM_BYTES    655360L	/* memory size for /dev/mem */
X  
X! /* Interrupt vectors */
X! #define DIVIDE_VECTOR      0	/* divide interrupt vector */
X! #define CLOCK_VECTOR       8	/* clock interrupt vector */
X! #define KEYBOARD_VECTOR    9	/* keyboard interrupt vector */
X! #define ETHER_VECTOR      11	/* ethernet interrupt vector */
X! #define SECONDARY_VECTOR  11	/* RS232 interrupt vector for port 2 */
X! #define	RS232_VECTOR      12	/* RS232 interrupt vector for port 1 */
X! #define XT_WINI_VECTOR	  13	/* xt winchester interrupt vector */
X! #define FLOPPY_VECTOR     14	/* floppy disk interrupt vector */
X! #define PRINTER_VECTOR    15	/* line printer interrupt vector */
X! #define SYS_VECTOR        32	/* system calls are made with int SYSVEC */
X! #define AT_WINI_VECTOR	 118	/* at winchester interrupt vector */
X! #define PS_KEYB_VECTOR	0x71	/* keyboard interrupt vector for PS/2 */
X  
X! /* The 8259A interrupt controller has to be re-enabled after each interrupt. */
X  #define INT_CTL         0x20	/* I/O port for interrupt controller */
X  #define INT_CTLMASK     0x21	/* setting bits in this port disables ints */
X! #define INT2_CTL	0xA0	/* I/O port for second interrupt controller */
X! #define INT2_MASK	0xA1	/* setting bits in this port disables ints */
X! #define ENABLE          0x20	/* code used to re-enable after an interrupt */
X! #define PCR		0x65	/* Planar Control Register */
X! #endif
X  
X! #define K_STACK_BYTES    512	/* how many bytes for the kernel stack */
X  
X! #define RET_REG            0	/* system call return codes go in this reg */
X! #define IDLE            -999	/* 'cur_proc' = IDLE means nobody is running */
X! 
X  /* The following items pertain to the 3 scheduling queues. */
X--- 3,92 ----
X  #ifdef i8088
X  
X! #define INIT_PSW      0x0200	/* initial psw */
X! #define INIT_TASK_PSW 0x1200	/* initial psw for tasks (with IOPL 1) */
X! 
X! /* Initial sp for mm, fs and init.
X!  *	2 bytes for short jump
X!  *	2 bytes unused
X!  *	3 words for init_org[] used by fs only
X!  *	3 words for real mode debugger trap
X!  *	3 words for save and restart temporaries
X!  *	3 words for interrupt
X!  * Leave no margin, to flush bugs early.
X   */
X! #define INIT_SP (2 + 2 + 3 * 2 + 3 * 2 + 3 * 2 + 3 * 2)
X  
X! #define HCLICK_SHIFT       4	/* log2 of HCLICK_SIZE */
X! #define HCLICK_SIZE       16	/* hardware segment conversion magic */
X  
X! #define ALIGNMENT	   4	/* align large items to a multiple of this */
X! #define VECTOR_BYTES     284	/* bytes of interrupt vectors to save */
X! 
X! /* Interrupt vectors defined/reserved by processor */
X! #define DIVIDE_VECTOR      0	/* divide error */
X! #define DEBUG_VECTOR       1	/* single step (trace) */
X! #define NMI_VECTOR         2	/* non-maskable interrupt */
X! #define BREAKPOINT_VECTOR  3	/* software breakpoint */
X! #define OVERFLOW_VECTOR    4	/* from INTO */
X  
X! /* Fixed system call vector (the only software interrupt). */
X! #define SYS_VECTOR        32	/* system calls are made with int SYSVEC */
X! 
X! /* Suitable irq bases for hardware interrupts.  Reprogram the 8259(s) from
X!  * the PC BIOS defaults since the BIOS doesn't respect all the processor's
X!  * reserved vectors (0 to 31).
X!  */
X! #define IRQ0_VECTOR     0x28	/* more or less arbitrary, but > 32 */
X! #define IRQ8_VECTOR     0x30 	/* together for simplicity */
X! 
X! /* Hardware interrupt numbers. */
X! #define CLOCK_IRQ          0
X! #define KEYBOARD_IRQ       1
X! #define CASCADE_IRQ        2	/* cascade enable for 2nd AT controller */
X! #define ETHER_IRQ          3	/* ethernet interrupt vector */
X! #define SECONDARY_IRQ      3	/* RS232 interrupt vector for port 2 */
X! #define RS232_IRQ          4	/* RS232 interrupt vector for port 1 */
X! #define XT_WINI_IRQ        5	/* xt winchester */
X! #define FLOPPY_IRQ         6	/* floppy disk */
X! #define PRINTER_IRQ        7
X! #define AT_WINI_IRQ       14	/* at winchester */
X! #define PS_KEYB_IRQ        9	/* keyboard interrupt vector for PS/2 */
X! 
X! /* Hardware vector numbers. */
X! #define CLOCK_VECTOR     ((CLOCK_IRQ & 0x07) + IRQ0_VECTOR)
X! #define KEYBOARD_VECTOR  ((KEYBOARD_IRQ & 0x07) + IRQ0_VECTOR)
X! #define ETHER_VECTOR     ((ETHER_IRQ & 0x07) + IRQ0_VECTOR)
X! #define SECONDARY_VECTOR ((SECONDARY_IRQ & 0x07) + IRQ0_VECTOR)
X! #define RS232_VECTOR     ((RS232_IRQ & 0x07) + IRQ0_VECTOR)
X! #define XT_WINI_VECTOR   ((XT_WINI_IRQ & 0x07) + IRQ0_VECTOR)
X! #define FLOPPY_VECTOR    ((FLOPPY_IRQ & 0x07) + IRQ0_VECTOR)
X! #define PRINTER_VECTOR   ((PRINTER_IRQ & 0x07) + IRQ0_VECTOR)
X! #define AT_WINI_VECTOR   ((AT_WINI_IRQ & 0x07) + IRQ8_VECTOR)
X! #define PS_KEYB_VECTOR   ((PS_KEYB_IRQ & 0x07) + IRQ8_VECTOR)
X! 
X! /* 8259A interrupt controller ports. */
X  #define INT_CTL         0x20	/* I/O port for interrupt controller */
X  #define INT_CTLMASK     0x21	/* setting bits in this port disables ints */
X! #define INT2_CTL        0xA0	/* I/O port for second interrupt controller */
X! #define INT2_MASK       0xA1	/* setting bits in this port disables ints */
X  
X! /* Magic numbers for interrupt controller. */
X! #define ENABLE          0x20	/* code used to re-enable after an interrupt */
X! 
X! /* Sizes of memory tables. */
X! #define NR_MEMS            4	/* number of chunks of memory */
X  
X! /* Magic memory locations and sizes. */
X! #define COLOR_BASE   0xB8000L	/* base of color video memory */
X! #define COLOR_SIZE    0x8000L	/* maximum usable color video memory */
X! #define MONO_BASE    0xB0000L	/* base of mono video memory */
X! #define MONO_SIZE     0x8000L	/* maximum usable mono video memory */
X! 
X! /* Misplaced stuff */
X! #define PCR		0x65	/* Planar Control Register */
X! 
X! #endif /* i8088 */
X! 
X! #define K_STACK_BYTES    512	/* how many bytes for the kernel stack */
X! 
X  /* The following items pertain to the 3 scheduling queues. */
X***************
X*** 55 ****
X--- 98,104 ----
X  #define printf        printk	/* the kernel really uses printk, not printf */
X+ 
X+ #if CLICK_SIZE >= HCLICK_SIZE
X+ #define click_to_hclick(n) ((n) << (CLICK_SHIFT - HCLICK_SHIFT))
X+ #else
X+ #define click_to_hclick(n) ((n) >> (HCLICK_SHIFT - CLICK_SHIFT))
X+ #endif
END_OF_FILE
if test 7031 -ne `wc -c <'kerneldif/const.h.cdif'`; then
    echo shar: \"'kerneldif/const.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/const.h.cdif'
fi
if test -f 'kerneldif/tty.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/tty.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/tty.c.cdif'\" \(808 characters\)
sed "s/^X//" >'kerneldif/tty.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/tty.c	Thu Oct 20 13:15:35 1988
X--- kernel/tty.c	Sat Mar 11 20:11:53 1989
X***************
X*** 160,162 ****
X    old_state = lock();
X!   ptr = m_ptr->ADDRESS;		/* pointer to accumulated char array */
X    copy_ptr = tty_copy_buf;	/* ptr to shadow array where chars copied */
X--- 160,162 ----
X    old_state = lock();
X!   ptr = tty_driver_buf;		/* pointer to accumulated char array */
X    copy_ptr = tty_copy_buf;	/* ptr to shadow array where chars copied */
X***************
X*** 168,170 ****
X  	*copy_ptr++ = *ptr++;	/* copy the array to safety */
X!   ptr = m_ptr->ADDRESS;
X    tty_buf_count(ptr) = 0;		/* accumulation count set to 0 */
X--- 168,170 ----
X  	*copy_ptr++ = *ptr++;	/* copy the array to safety */
X!   ptr = tty_driver_buf;
X    tty_buf_count(ptr) = 0;		/* accumulation count set to 0 */
END_OF_FILE
if test 808 -ne `wc -c <'kerneldif/tty.c.cdif'`; then
    echo shar: \"'kerneldif/tty.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/tty.c.cdif'
fi
echo shar: End of archive 3 \(of 10\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 4 - By Bruce Evans
Message-ID: <5266@ditmela.oz>
Date: 18 May 89 01:23:11 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1328


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 10)."
# Contents:  kerneldif/dmp.c.cdif kerneldif/exception.c.cd
#   kerneldif/floppy.c.cdif kerneldif/glo.h.cdif
#   kerneldif/i8259.c.cdif kerneldif/klib286.x.cdif
#   kerneldif/main.c.cdif mmdif/signal.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:03 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/dmp.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/dmp.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/dmp.c.cdif'\" \(4759 characters\)
sed "s/^X//" >'kerneldif/dmp.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/dmp.c	Wed Aug  3 21:18:41 1988
X--- kernel/dmp.c	Sun Mar 12 16:15:21 1989
X***************
X*** 22,24 ****
X   *===========================================================================*/
X! p_dmp()
X  {
X--- 22,24 ----
X   *===========================================================================*/
X! PUBLIC p_dmp()
X  {
X***************
X*** 28,31 ****
X    char *np;
X!   vir_bytes base, limit, first, last;
X!   phys_bytes ltmp, dst;
X    int index;
X--- 28,31 ----
X    char *np;
X!   phys_clicks base, size;
X!   phys_bytes dst;
X    int index;
X***************
X*** 34,52 ****
X    printf(
X!  "\nproc  -pid- -pc-  -sp-  flag  user  -sys-  base limit recv   command\r\n");
X  
X!   dst = umap(proc_addr(SYSTASK), D, (vir_bytes)nbuff, NSIZE);
X  
X!   for (rp = &proc[0]; rp < &proc[NR_PROCS+NR_TASKS]; rp++)  {
X  	if (rp->p_flags & P_SLOT_FREE) continue;
X! 	first = rp->p_map[T].mem_phys;
X! 	last = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
X! 	ltmp = ((long) first << 4) + 512L;
X! 	base = (vir_bytes) (ltmp/1024L);
X! 	ltmp = (((long) last << 4) + 512L);
X! 	limit = (vir_bytes) (ltmp/1024L);
X! 	prname(rp - proc);
X! 	printf(" %4d %4x %4x %4x %6D %7D  %3dK %3dK  ",
X! 		rp->p_pid, rp->p_pcpsw.pc, rp->p_sp, rp->p_flags,
X  		rp->user_time, rp->sys_time,
X! 		base, limit);
X  		if (rp->p_flags == 0)
X--- 34,51 ----
X    printf(
X!   "\r\nproc  --pid -pc- -sp flag -user- --sys-- -base- -size-  recv- command\r\n");
X  
X!   dst = umap(cproc_addr(SYSTASK), D, (vir_bytes)nbuff, NSIZE);
X  
X!   for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++)  {
X  	if (rp->p_flags & P_SLOT_FREE) continue;
X! 	base = rp->p_map[T].mem_phys;
X! 	size = rp->p_map[S].mem_phys + rp->p_map[S].mem_len - base;
X! 	prname(proc_number(rp));
X! 	printf("%5u %4lx %4lx %2x %7U %7U %5uK %5uK  ",
X! 		rp->p_pid,
X! 		(unsigned long) rp->p_reg.r16.pc,
X! 		(unsigned long) rp->p_reg.r16.sp,
X! 		rp->p_flags,
X  		rp->user_time, rp->sys_time,
X! 		click_to_round_k(base), click_to_round_k(size));
X  		if (rp->p_flags == 0)
X***************
X*** 54,62 ****
X  		else
X! 			prname(NR_TASKS + rp->p_getfrom);
X  
X  	/* Fetch the command string from the user process. */
X! 	index = rp - proc - NR_TASKS;
X  	if (index > LOW_USER && aout[index] != 0) {
X  		phys_copy(aout[index], dst, (long) NSIZE);
X- 		aout[NSIZE] = 0;
X  		for (np = &nbuff[0]; np < &nbuff[NSIZE]; np++)
X--- 53,60 ----
X  		else
X! 			prname(rp->p_getfrom);
X  
X  	/* Fetch the command string from the user process. */
X! 	index = proc_number(rp);
X  	if (index > LOW_USER && aout[index] != 0) {
X  		phys_copy(aout[index], dst, (long) NSIZE);
X  		for (np = &nbuff[0]; np < &nbuff[NSIZE]; np++)
X***************
X*** 75,93 ****
X  
X! map_dmp()
X  {
X    register struct proc *rp;
X!   vir_bytes base, limit, first, last;
X!   phys_bytes ltmp;
X  
X!   printf("\nPROC   -----TEXT-----  -----DATA-----  ----STACK-----  BASE SIZE\r\n");
X!   for (rp = &proc[NR_TASKS]; rp < &proc[NR_TASKS+NR_PROCS]; rp++)  {
X  	if (rp->p_flags & P_SLOT_FREE) continue;
X! 	first = rp->p_map[T].mem_phys;
X! 	last = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
X! 	ltmp = ((long) first << 4) + 512L;
X! 	base = (vir_bytes) (ltmp/1024L);
X! 	ltmp = (((long) (last-first) << 4) + 512L);
X! 	limit = (vir_bytes) (ltmp/1024L);
X! 	prname(rp-proc);
X! 	printf(" %4x %4x %4x  %4x %4x %4x  %4x %4x %4x  %3dK %3dK\r\n", 
X  	    rp->p_map[T].mem_vir, rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
X--- 73,86 ----
X  
X! PUBLIC map_dmp()
X  {
X    register struct proc *rp;
X!   phys_clicks base, size;
X  
X!   printf("\r\nPROC   -----TEXT-----  -----DATA-----  ----STACK-----  -BASE- -SIZE-\r\n");
X!   for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++)  {
X  	if (rp->p_flags & P_SLOT_FREE) continue;
X! 	base = rp->p_map[T].mem_phys;
X! 	size = rp->p_map[S].mem_phys + rp->p_map[S].mem_len - base;
X! 	prname(proc_number(rp));
X! 	printf(" %4x %4x %4x  %4x %4x %4x  %4x %4x %4x  %5uK %5uK\r\n", 
X  	    rp->p_map[T].mem_vir, rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
X***************
X*** 95,97 ****
X  	    rp->p_map[S].mem_vir, rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
X! 	    base, limit);
X    }
X--- 88,90 ----
X  	    rp->p_map[S].mem_vir, rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
X! 	    click_to_round_k(base), click_to_round_k(size));
X    }
X***************
X*** 100,113 ****
X  
X! prname(i)
X  int i;
X  {
X!   if (i == ANY+NR_TASKS)
X  	printf("ANY   ");
X!   else if (i >= 0 && i <= NR_TASKS+2)
X! 	printf("%s", tasktab[i].name);
X    else
X! 	printf("%4d  ", i-NR_TASKS);
X  }
X  
X! set_name(proc_nr, ptr)
X  int proc_nr;
X--- 93,106 ----
X  
X! PRIVATE prname(i)
X  int i;
X  {
X!   if (i == ANY)
X  	printf("ANY   ");
X!   else if ( (unsigned) (i + NR_TASKS) <= LOW_USER + NR_TASKS)
X! 	printf("%s", tasktab[i + NR_TASKS].name);
X    else
X! 	printf("%4d  ", i);
X  }
X  
X! PUBLIC set_name(proc_nr, ptr)
X  int proc_nr;
END_OF_FILE
if test 4759 -ne `wc -c <'kerneldif/dmp.c.cdif'`; then
    echo shar: \"'kerneldif/dmp.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/dmp.c.cdif'
fi
if test -f 'kerneldif/exception.c.cd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/exception.c.cd'\"
else
echo shar: Extracting \"'kerneldif/exception.c.cd'\" \(2371 characters\)
sed "s/^X//" >'kerneldif/exception.c.cd' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/exception.c	Thu Mar 23 01:26:57 1989
X***************
X*** 0 ****
X--- 1,67 ----
X+ /* This file contains a simple exception handler.  Exceptions in user
X+  * processes are converted to signals.  Exceptions in the kernel, MM and
X+  * FS cause a panic.
X+  */
X+ 
X+ #include "../h/const.h"
X+ #include "../h/type.h"
X+ #include "../h/signal.h"
X+ #include "const.h"
X+ #include "type.h"
X+ #include "glo.h"
X+ #include "proc.h"
X+ 
X+ /*==========================================================================*
X+  *				exception				    *
X+  *==========================================================================*/
X+ PUBLIC exception(vec_nr)
X+ unsigned vec_nr;
X+ {
X+ /* An exception or unexpected interrupt has occurred. */
X+ 
X+   struct ex_s {
X+ 	char *msg;
X+ 	int signum;
X+ 	int minprocessor;
X+   };
X+   static struct ex_s ex_data[] = {
X+ 	"Divide error", SIGFPE, 86,
X+ 	"Debug exception", SIGTRAP, 86,		/* overidden by debugger */
X+ 	"Nonmaskable interrupt", SIGBUS, 86,	/* needs separate handler */
X+ 	"Breakpoint", SIGTRAP, 86,		/* overidden by debugger */
X+ 	"Overflow", SIGFPE, 86,
X+ 	"Bounds check", SIGFPE, 186,
X+ 	"Invalid opcode", SIGILL, 186,
X+ 	"Coprocessor not available", SIGFPE, 186,
X+ 	"Double fault", SIGBUS, 286,
X+ 	"Copressor segment overrun", SIGSEGV, 286,
X+ 	"Invalid TSS", SIGSEGV, 286,
X+ 	"Segment not present", SIGSEGV, 286,
X+ 	"Stack exception", SIGSEGV, 286,	/* STACK_FAULT already used */
X+ 	"General protection", SIGSEGV, 286,
X+ 	"Page fault", SIGSEGV, 386,		/* not close */
X+ 	NIL_PTR, SIGILL, 0,			/* probably software trap */
X+ 	"Coprocessor error", SIGFPE, 386,
X+ 	"Unexpected interrupt along vector >= 17", SIGILL, 0,
X+   };
X+   register struct ex_s *ep;
X+ 
X+   ep = &ex_data[vec_nr];
X+ 
X+   if (k_reenter == 0 && isuserp(proc_ptr)) {
X+ 	unlock();		/* this is protected like sys_call() */
X+ 	cause_sig(proc_number(proc_ptr), ep->signum);
X+ 	return;
X+   }
X+ 
X+   /* This is not supposed to happen. */
X+   if (ep->msg == NIL_PTR || get_processor() < ep->minprocessor)
X+ 	printf("\r\nIntel-reserved exception %d\r\n", vec_nr);
X+   else
X+ 	printf("\r\n%s\r\n", ep->msg);
X+   printf("process number %d, pc = 0x%04x:0x%04lx\r\n",
X+ 	 proc_number(proc_ptr),
X+ 	 (unsigned long) proc_ptr->p_reg.r16.cs,
X+ 	 (unsigned long) proc_ptr->p_reg.r16.pc);
X+   panic("exception in kernel, mm or fs", NO_NUM);
X+ }
END_OF_FILE
if test 2371 -ne `wc -c <'kerneldif/exception.c.cd'`; then
    echo shar: \"'kerneldif/exception.c.cd'\" unpacked with wrong size!
fi
# end of 'kerneldif/exception.c.cd'
fi
if test -f 'kerneldif/floppy.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/floppy.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/floppy.c.cdif'\" \(3990 characters\)
sed "s/^X//" >'kerneldif/floppy.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/floppy.c	Thu Jan 26 04:51:41 1989
X--- kernel/floppy.c	Fri Mar 10 00:03:28 1989
X***************
X*** 344,346 ****
X  
X!   int mode, low_addr, high_addr, top_addr, low_ct, high_ct, top_end, s;
X    vir_bytes vir, ct;
X--- 344,346 ----
X  
X!   int mode, low_addr, high_addr, top_addr, low_ct, high_ct, top_end;
X    vir_bytes vir, ct;
X***************
X*** 370,372 ****
X    port_out(DMA_INIT, DMA_RESET_VAL);        /* reset the dma controller */
X-   s = lock();
X    port_out(DMA_M2, mode);	/* set the DMA mode */
X--- 370,371 ----
X***************
X*** 378,380 ****
X    port_out(DMA_COUNT, high_ct);	/* output high 8 bits of count - 1 */
X-   restore(s);
X    port_out(DMA_INIT, 2);	/* initialize DMA */
X--- 377,378 ----
X***************
X*** 399,405 ****
X   * turning off motors while we are testing the bits.
X   */
X  
X!   int motor_bit, running, send_mess(), old_state;
X  
X-   old_state = lock();		/* no interrupts while checking out motor */
X    motor_bit = 1 << (fp->fl_drive + 4);	/* bit mask for this drive */
X--- 397,403 ----
X   * turning off motors while we are testing the bits.
X+  * NO NEED, the clock task cannot run while another (FLOPPY) task is active.
X   */
X  
X!   int motor_bit, running, send_mess();
X  
X    motor_bit = 1 << (fp->fl_drive + 4);	/* bit mask for this drive */
X***************
X*** 411,413 ****
X    prev_motor = motor_bit;	/* record motor started for next time */
X-   restore(old_state);
X  
X--- 409,410 ----
X***************
X*** 486,488 ****
X    int r, s, op;
X-   extern int olivetti;
X  
X--- 483,484 ----
X***************
X*** 533,537 ****
X  /*===========================================================================*
X!  *				fdc_results				     * 
X   *===========================================================================*/
X! PRIVATE int fdc_results(fp)
X  register struct floppy *fp;	/* pointer to the drive struct */
X--- 529,533 ----
X  /*===========================================================================*
X!  *				old_fdc_results				     * 
X   *===========================================================================*/
X! PRIVATE int old_fdc_results(fp)
X  register struct floppy *fp;	/* pointer to the drive struct */
X***************
X*** 651,658 ****
X  
X!   int i, r, status, old_state;
X    register struct floppy *fp;
X  
X!   /* Disable interrupts and strobe reset bit low. */
X    need_reset = FALSE;
X!   old_state = lock();
X    motor_status = 0;
X--- 647,656 ----
X  
X!   int i, r, status;
X    register struct floppy *fp;
X  
X!   /* Disable interrupts and strobe reset bit low.  *This* lock is essential
X!    * because the controller may interrupt twice, once for each port_out().
X!    */
X    need_reset = FALSE;
X!   lock();
X    motor_status = 0;
X***************
X*** 661,663 ****
X    port_out(DOR, ENABLE_INT);	/* strobe it high again */
X!   restore(old_state);		/* interrupts allowed again */
X    receive(HARDWARE, &mess);	/* collect the RESET interrupt */
X--- 659,661 ----
X    port_out(DOR, ENABLE_INT);	/* strobe it high again */
X!   unlock();			/* interrupts allowed again */
X    receive(HARDWARE, &mess);	/* collect the RESET interrupt */
X***************
X*** 668,669 ****
X--- 666,671 ----
X  	fdc_results(&floppy[i]);/* get results (using each floppy[i]) */
X+ 				/* it looks wrong to have the sense command
X+ 				 * and the enable in fdc_results()
X+ 				 * inside this loop
X+ 				 */
X  	floppy[i].fl_calibration = UNCALIBRATED;
X***************
X*** 703,704 ****
X--- 705,724 ----
X    send(FLOPPY, &mess);
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				fdc_results				    *
X+  *==========================================================================*/
X+ PRIVATE int fdc_results(fp)
X+ register struct floppy *fp;	/* pointer to the drive struct */
X+ {
X+ /* Extract results from the controller after an operation, then reenable the
X+  * interrupt controller.  The sense command should be done here too.
X+  */
X+ 
X+   int r;
X+ 
X+   r = old_fdc_results(fp);
X+   cim_floppy();
X+   return(r);
X  }
END_OF_FILE
if test 3990 -ne `wc -c <'kerneldif/floppy.c.cdif'`; then
    echo shar: \"'kerneldif/floppy.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/floppy.c.cdif'
fi
if test -f 'kerneldif/glo.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/glo.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/glo.h.cdif'\" \(2154 characters\)
sed "s/^X//" >'kerneldif/glo.h.cdif' <<'END_OF_FILE'
X*** kernel-1.3/glo.h	Thu Oct 20 13:15:23 1988
X--- kernel/glo.h	Sun Mar 12 22:03:33 1989
X***************
X*** 2,12 ****
X  
X! /* Clocks and timers */
X! EXTERN real_time realtime;	/* real time clock */
X! EXTERN int lost_ticks;		/* incremented when clock int can't send mess*/
X! 
X! /* Processes, signals, and messages. */
X! EXTERN int cur_proc;		/* current process */
X! EXTERN int prev_proc;		/* previous process */
X  EXTERN int sig_procs;		/* number of procs with p_pending != 0 */
X- EXTERN message int_mess;	/* interrupt routines build message here */
X  
X--- 2,5 ----
X  
X! /* Signals. */
X  EXTERN int sig_procs;		/* number of procs with p_pending != 0 */
X  
X***************
X*** 16,17 ****
X--- 9,11 ----
X  EXTERN int port_65;		/* saved contents of Planar Control Register */
X+ EXTERN unsigned processor;	/* 86, 186, 286, 386, ... */
X  
X***************
X*** 21 ****
X--- 15,41 ----
X  EXTERN int scan_code;		/* scan code of key pressed to start minix */
X+ EXTERN int snow;		/* 1 if screen needs snow removal, 0 if not */
X+ 
X+ /* Low level interrupt communications. */
X+ EXTERN struct proc *held_head;	/* head of queue of held-up interrupts */
X+ EXTERN struct proc *held_tail;	/* tail of queue of held-up interrupts */
X+ EXTERN unsigned char k_reenter;	/* kernel reentry count (entry count less 1)*/
X+ 
X+ /* Memory sizes. */
X+ #ifdef i8088
X+ EXTERN phys_clicks membase[NR_MEMS];	/* bases of chunks of memory */
X+ EXTERN phys_clicks memsize[NR_MEMS];	/* sizes of chunks of memory */
X+ EXTERN unsigned char memtype[NR_MEMS];	/* types of chunks of memory */
X+ #endif
X+ 
X+ /* Miscellaneous (still all over the place in non-header files). */
X+ extern unsigned sizes[8];		/* table filled in by build */
X+ extern struct tasktab tasktab[];	/* see table.c */
X+ extern char t_stack[];			/* see table.c */
X+ extern int vec_table[VECTOR_BYTES/ sizeof (int)];  /* copy of BIOS vectors */
X+ 
X+ /* Non-integer functions (still all over the place in non-header files). */
X+ extern phys_bytes umap();	/* map user address to physical address */
X+ #ifdef i8088
X+ extern unsigned codeseg();	/* current code segment */
X+ extern unsigned dataseg();	/* current data segment */
X+ #endif
END_OF_FILE
if test 2154 -ne `wc -c <'kerneldif/glo.h.cdif'`; then
    echo shar: \"'kerneldif/glo.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/glo.h.cdif'
fi
if test -f 'kerneldif/i8259.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/i8259.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/i8259.c.cdif'\" \(2394 characters\)
sed "s/^X//" >'kerneldif/i8259.c.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/i8259.c	Sun Mar 12 22:59:02 1989
X***************
X*** 0 ****
X--- 1,66 ----
X+ /* This file contains routines for initializing the 8259 interrupt controller:
X+  *	enable_irq:	enable an interrupt line.  The cim...() functions in
X+  *			klib88 are specialized versions of this
X+  *	init_8259:	initialize the 8259(s), since the BIOS does it wrong
X+  */
X+ 
X+ #include "../h/const.h"
X+ #include "../h/type.h"
X+ #include "../h/com.h"
X+ #include "const.h"
X+ #include "type.h"
X+ #include "glo.h"
X+ 
X+ #define ICW1_AT         0x11	/* edge triggered, cascade, need ICW4 */
X+ #define ICW1_PC         0x13	/* edge triggered, no cascade, need ICW4 */
X+ #define ICW3_M          0x04	/* bit 2 for slave on channel 2 */
X+ #define ICW3_S          0x02	/* slave identity is 2 */
X+ #define ICW4_AT         0x01	/* not SFNM, not buffered, normal EOI, 8086 */
X+ #define ICW4_PC         0x09	/* not SFNM, buffered, normal EOI, 8086 */
X+ 
X+ 
X+ /*==========================================================================*
X+  *				enable_irq				    *
X+  *==========================================================================*/
X+ PUBLIC enable_irq(irq_nr)
X+ unsigned irq_nr;
X+ {
X+ /* Clear the corresponding 8259 register bit. */
X+ 
X+   int old_state;
X+ 
X+   old_state = lock();
X+   if (irq_nr < 8)
X+ 	port_out(INT_CTLMASK, inportb(INT_CTLMASK) & ~(1 << irq_nr));
X+   else 
X+ 	port_out(INT2_MASK, inportb(INT2_MASK) & ~(1 << (irq_nr - 8)));
X+   restore(old_state);
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				init_8259				    *
X+  *==========================================================================*/
X+ PUBLIC init_8259(master_base, slave_base)
X+ unsigned master_base;
X+ unsigned slave_base;
X+ {
X+ /* Initialize the 8259(s), finishing with all interrupts disabled. */
X+ 
X+   if (pc_at) {
X+ 	port_out(INT_CTL, ICW1_AT);
X+ 	port_out(INT_CTLMASK, master_base);	/* ICW2 for master */
X+ 	port_out(INT_CTLMASK, ICW3_M);
X+ 	port_out(INT_CTLMASK, ICW4_AT);
X+ 	port_out(INT2_CTL, ICW1_AT);
X+ 	port_out(INT2_MASK, slave_base);	/* ICW2 for slave */
X+ 	port_out(INT2_MASK, ICW3_S);
X+ 	port_out(INT2_MASK, ICW4_AT);
X+ 	port_out(INT2_MASK, ~0);
X+   } else {
X+ 	port_out(INT_CTL, ICW1_PC);
X+ 	port_out(INT_CTLMASK, master_base);	/* no slave */
X+ 	port_out(INT_CTLMASK, ICW4_PC);
X+   }
X+   port_out(INT_CTLMASK, ~0);
X+ }
END_OF_FILE
if test 2394 -ne `wc -c <'kerneldif/i8259.c.cdif'`; then
    echo shar: \"'kerneldif/i8259.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/i8259.c.cdif'
fi
if test -f 'kerneldif/klib286.x.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/klib286.x.cdif'\"
else
echo shar: Extracting \"'kerneldif/klib286.x.cdif'\" \(8420 characters\)
sed "s/^X//" >'kerneldif/klib286.x.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/klib286.x	Mon Mar 13 04:51:55 1989
X***************
X*** 0 ****
X--- 1,301 ----
X+ |*===========================================================================*
X+ |*			klib support for 286 protected mode		     *
X+ |*===========================================================================*
X+ 
X+ #include "../h/const.h"
X+ #include "const.h"
X+ #include "protect.h"
X+ #include "sconst.h"
X+ #define KLIB286 .define
X+ #include "sglo.h"
X+ 
X+ 	.text
X+ |*===========================================================================*
X+ |*				klib286_init				     *
X+ |*===========================================================================*
X+ 
X+ | Patch the code segment for returning to real mode.
X+ | Patch various functions in klib88 to jump to corresponding functions here.
X+ 
X+ _klib286_init:
X+ 	mov	si,#patch_table
X+ 	lodw			| original function
X+ patch1:
X+ 	mov	bx,ax
X+ 	lodw			| new function - target of call or jump
X+ 	sub	ax,bx		| relative jump
X+ 	sub	ax,#3		| adjust by length of jump instruction
X+ 	seg	cs
X+ 	mov	1(bx),ax
X+ 	lodb			| opcode
X+ 	seg	cs
X+ 	movb	(bx),al
X+ 	lodw			| next original function
X+ 	test	ax,ax
X+ 	jnz	patch1
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_check_mem				     *
X+ |*===========================================================================*
X+ 
X+ PCM_DENSITY	=	256	| others are not supported
X+ 
X+ p_check_mem:
X+ 	pop	bx
X+ 	pop	_gdt+DS_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop base into base of source descriptor
X+ 	movb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	pop	cx		| byte count in dx:cx
X+ 	pop	dx
X+ 	sub	sp,#4+4
X+ 	push	bx
X+ 	push	ds
X+ 
X+ 	sub	ax,ax		| prepare for early exit
X+ 	test	dx,#0xFF00
X+ 	jnz	pcm_1exit	| can't handle bases above 16M
X+ 	movb	cl,ch		| divide size by 256 and discard high byte
X+ 	movb	ch,dl
X+ 	push	cx		| save divided size
X+ 	sub	bx,bx		| test bytes at bases of segments
X+ pcm_loop:
X+ 	mov	ax,#DS_286_SELECTOR
X+ 	mov	ds,ax
X+ 	movb	dl,#TEST1PATTERN
X+ 	xchgb	dl,(bx)		| write test pattern, remember original value
X+ 	xchgb	dl,(bx)		| restore original value, read test pattern
X+ 	cmpb	dl,#TEST1PATTERN	| must agree if good real memory
X+ 	jnz	pcm_exit	| if different, memory is unusable
X+ 	movb	dl,#TEST2PATTERN
X+ 	xchgb	dl,(bx)
X+ 	xchgb	dl,(bx)
X+ 	cmpb	dl,#TEST2PATTERN
X+ 	jnz	pcm_exit
X+ 	seg	es		| next segement, test for wraparound at 16M
X+ 	add	_gdt+DS_286_OFFSET+DESC_BASE,#PCM_DENSITY
X+ 	seg	es		| assuming es == old ds
X+ 	adcb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,#0
X+ 	loopnz	pcm_loop
X+ 
X+ pcm_exit:
X+ 	pop	ax
X+ 	sub	ax,cx		| verified size in multiples of PCM_DENSITY
X+ pcm_1exit:
X+ 	movb	dl,ah		| convert to phys_bytes in dx:ax
X+ 	subb	dh,dh
X+ 	movb	ah,al
X+ 	movb	al,dh
X+ 	pop	ds
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_cp_mess				     *
X+ |*===========================================================================*
X+ 
X+ | The 16 bit cp_mess() attempts to be efficient by passing raw segments but
X+ | that just gets in the way here.
X+ 
X+ p_cp_mess:
X+ 	pop	dx
X+ 	pop	bx		| proc
X+ 	pop	cx		| source clicks
X+ 	pop	ax		| source offset
X+ #if CLICK_SHIFT != HCLICK_SHIFT + 4
X+ #error /* the only click size supported is 256, to avoid slow shifts here */
X+ #endif
X+ 	addb	ah,cl		| calculate source offset
X+ 	adcb	ch,#0 		| and put in base of source descriptor
X+ 	mov	_gdt+DS_286_OFFSET+DESC_BASE,ax
X+ 	movb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,ch
X+ 	pop	cx		| destination clicks
X+ 	pop	ax		| destination offset
X+ 	addb	ah,cl		| calculate destination offset
X+ 	adcb	ch,#0 		| and put in base of destination descriptor
X+ 	mov	_gdt+ES_286_OFFSET+DESC_BASE,ax
X+ 	movb	_gdt+ES_286_OFFSET+DESC_BASE_MIDDLE,ch
X+ 	sub	sp,#2+2+2+2+2
X+ 
X+ 	push	ds
X+ 	push	es
X+ 	mov	ax,#DS_286_SELECTOR
X+ 	mov	ds,ax
X+ 	mov	ax,#ES_286_SELECTOR
X+ 	mov	es,ax
X+ 
X+ 	seg	es
X+ 	mov	0,bx		| sender's proc no. from arg, not msg
X+ 	mov	ax,si
X+ 	mov	bx,di
X+ 	mov	si,#2		| src offset is now 2 relative to start of seg
X+ 	mov	di,si		| and destination offset
X+ 	mov	cx,#Msize-1	| word count
X+ 	rep
X+ 	movw
X+ 	mov	di,bx
X+ 	mov	si,ax
X+ 	pop	es
X+ 	pop	ds
X+ 	jmpreg	(dx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_get_phys_byte				     *
X+ |*===========================================================================*
X+ 
X+ p_get_phys_byte:
X+ 	pop	dx
X+ 	pop	_gdt+DS_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop source into base of source descriptor
X+ 	movb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	sub	sp,#4
X+ 	mov	cx,ds
X+ 	mov	ax,#DS_286_SELECTOR
X+ 	pushf			| lock may be necessary since this is (only)
X+ 	cli			| called by the badly behaved printer task
X+ 	mov	ds,ax
X+ 	movb	al,0		| get the byte from the start of the segment
X+ 	mov	ds,cx
X+ 	popf
X+ 	subb	ah,ah
X+ 	jmpreg	(dx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_phys_copy				     *
X+ |*===========================================================================*
X+ 
X+ p_phys_copy:
X+ 	pop	dx
X+ 	pop	_gdt+DS_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop source into base of source descriptor
X+ 	movb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	pop	_gdt+ES_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop destination into base of dst descriptor
X+ 	movb	_gdt+ES_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	pop	cx		| byte count in bx:cx
X+ 	pop	bx
X+ 	sub	sp,#4+4+4
X+ 
X+ 	push	di
X+ 	push	si
X+ 	push	es
X+ 	push	ds
X+ 	sub	si,si		| src offset is now 0 relative to start of seg
X+ 	mov	di,si		| and destination offset
X+ 	j	ppc_next
X+ 
X+ | It is too much trouble to align the segment bases so word alignment is hard.
X+ | Avoiding the book-keeping for alignment may be good anyway.
X+ 
X+ ppc_large:
X+ 	push	cx
X+ 	mov	cx,#0x8000	| copy a large chunk of this many words
X+ 	rep
X+ 	movw
X+ 	pop	cx
X+ 	dec	bx
X+ 	pop	ds		| update the descriptors
X+ 	incb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE
X+ 	incb	_gdt+ES_286_OFFSET+DESC_BASE_MIDDLE
X+ 	push	ds
X+ ppc_next:
X+ 	mov	ax,#DS_286_SELECTOR	| (re)load the selectors
X+ 	mov	ds,ax
X+ 	mov	ax,#ES_286_SELECTOR
X+ 	mov	es,ax
X+ 	test	bx,bx
X+ 	jnz	ppc_large
X+ 
X+ 	shr	cx,#1		| word count
X+ 	rep
X+ 	movw			| move any leftover words
X+ 	rcl	cx,#1		| restore old bit 0
X+ 	rep
X+ 	movb			| move any leftover byte
X+ 	pop	ds
X+ 	pop	es
X+ 	pop	si
X+ 	pop	di
X+ 	jmpreg	(dx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_port_read				     *
X+ |*===========================================================================*
X+ 
X+ | This is not reentrant, but only the WINCHESTER task is allowed to call it.
X+ 
X+ p_port_read:
X+ 	pop	bx
X+ 	pop	dx		| port
X+ 	pop	_gdt+ES_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop destination into base of dst descriptor
X+ 	movb	_gdt+ES_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	pop	cx		| byte count
X+ 	sub	sp,#2+4+2
X+ 	push	es
X+ 	mov	ax,#ES_286_SELECTOR
X+ 	mov	es,ax
X+ 	mov	ax,di
X+ 	sub	di,di		| dst offset is now 0 relative to start of seg
X+ 	shr	cx,#1		| word count
X+ 	rep
X+ 	insw			| read everything
X+ 	mov	di,ax
X+ 	pop	es
X+ 	jmpreg	(bx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_port_write				     *
X+ |*===========================================================================*
X+ 
X+ p_port_write:
X+ 	pop	bx
X+ 	pop	dx		| port
X+ 	pop	_gdt+DS_286_OFFSET+DESC_BASE
X+ 	pop	ax		| pop offset into base of source descriptor
X+ 	movb	_gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,al
X+ 	pop	cx		| byte count, discard high word
X+ 	sub	sp,#2+4+2
X+ 	push	ds
X+ 	mov	ax,#DS_286_SELECTOR
X+ 	mov	ds,ax
X+ 	mov	ax,si
X+ 	sub	si,si		| src offset is now 0 relative to start of seg
X+ 	shr	cx,#1		| word count
X+ 	rep
X+ 	outsw			| write everything
X+ 	mov	si,ax
X+ 	pop	ds
X+ 	jmpreg	(bx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				data					     *
X+ |*===========================================================================*
X+ 
X+ 	.data
X+ 
X+ patch_table:			| triples (old function, new function, opcode)
X+ 	.word	_check_mem, p_check_mem
X+ 	.byte	JMP_OPCODE
X+ 	.word	_cp_mess, p_cp_mess
X+ 	.byte	JMP_OPCODE
X+ 	.word	_get_phys_byte, p_get_phys_byte
X+ 	.byte	JMP_OPCODE
X+ 	.word	_phys_copy, p_phys_copy
X+ 	.byte	JMP_OPCODE
X+ 	.word	_port_read, p_port_read
X+ 	.byte	JMP_OPCODE
X+ 	.word	_port_write, p_port_write
X+ 	.byte	JMP_OPCODE
X+ 	.word	_restart, p_restart
X+ 	.byte	JMP_OPCODE
X+ 	.word	save, p2_save
X+ 	.byte	JMP_OPCODE
X+ 	.word	0		| end of table
X+ 
END_OF_FILE
if test 8420 -ne `wc -c <'kerneldif/klib286.x.cdif'`; then
    echo shar: \"'kerneldif/klib286.x.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/klib286.x.cdif'
fi
if test -f 'kerneldif/main.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/main.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/main.c.cdif'\" \(13597 characters\)
sed "s/^X//" >'kerneldif/main.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/main.c	Thu Oct  6 21:07:39 1988
X--- kernel/main.c	Thu Mar 23 04:06:52 1989
X***************
X*** 7,10 ****
X   *   main:		MINIX main program
X-  *   unexpected_int:	called on an interrupt to an unused vector < 16 occurs
X-  *   trap:		called on an unexpected trap to a vector >= 16 occurs
X   *   panic:		abort MINIX due to a fatal error
X--- 7,8 ----
X***************
X*** 14,15 ****
X--- 12,14 ----
X  #include "../h/type.h"
X+ #include "../h/boot.h"
X  #include "../h/callnr.h"
X***************
X*** 23,26 ****
X  
X! #define SAFETY             8	/* margin of safety for stack overflow (ints)*/
X! #define VERY_BIG       39328	/* must be bigger than kernel size (clicks) */
X  #define BASE            1536	/* address where MINIX starts in memory */
X--- 22,31 ----
X  
X! #define CLOCK_MASK	(1 << (CLOCK_IRQ & 0x07))
X! #define CASCADE_MASK	(1 << (CASCADE_IRQ & 0x07))
X! #define XT_WINI_MASK	(1 << (XT_WINI_IRQ & 0x07))
X! #define FLOPPY_MASK	(1 << (FLOPPY_IRQ & 0x07))
X! #define PRINTER_MASK	(1 << (PRINTER_IRQ & 0x07))
X! #define AT_WINI_MASK	(1 << (AT_WINI_IRQ & 0x07))
X! 
X! #define SAFETY            32	/* safety margin for stack overflow (bytes) */
X  #define BASE            1536	/* address where MINIX starts in memory */
X***************
X*** 31,38 ****
X  #define PS              0xFA	/* IBM code for PS/2  (in BIOS at 0xFFFFE) */
X- #define EM_VEC          0x15	/* vector for extended memory BIOS calls */
X- #define CMASK1          0x00	/* interrupt mask: ptr, dsk, keybd, clk, PIC */
X- #define CMASK2          0xBF	/* interrupt mask for secondary PIC */
X- #define CMASK3          0x3C	/* interrupt mask for PS/2 */
X  #define CMASK4          0x9E	/* Planar Control Register */
X! #define HIGH_INT          16	/* limit of the interrupt vectors */
X  
X--- 36,39 ----
X  #define PS              0xFA	/* IBM code for PS/2  (in BIOS at 0xFFFFE) */
X  #define CMASK4          0x9E	/* Planar Control Register */
X! #define HIGH_INT          17	/* limit of the interrupt vectors */
X  
X***************
X*** 40,44 ****
X             int07(), int08(), int09(), int10(), int11(), int12(), int13(), 
X!            int14(), int15();
X  int (*int_vec[HIGH_INT])() = {int00, int01, int02, int03, int04, int05, int06,
X!     int07, int08, int09, int10, int11, int12, int13, int14, int15};     
X  
X--- 41,45 ----
X             int07(), int08(), int09(), int10(), int11(), int12(), int13(), 
X!            int14(), int15(), int16();
X  int (*int_vec[HIGH_INT])() = {int00, int01, int02, int03, int04, int05, int06,
X!     int07, int08, int09, int10, int11, int12, int13, int14, int15, int16};
X  
X***************
X*** 54,56 ****
X    register int t;
X-   int i, old_state;
X    vir_clicks size;
X--- 55,56 ----
X***************
X*** 59,61 ****
X    int	stack_size;
X!   int * ktsb;			/* kernel task stack base */
X    extern unsigned sizes[8];	/* table filled in by build */
X--- 59,61 ----
X    int	stack_size;
X!   offset_t ktsb;		/* kernel task stack base */
X    extern unsigned sizes[8];	/* table filled in by build */
X***************
X*** 65,70 ****
X    extern phys_bytes umap();
X-   extern char get_byte();
X    extern struct tasktab tasktab[];	/* see table.c */
X!   extern int t_stack[];			/* see table.c */
X!   extern int k_stack[];			/* see table.c */
X  
X--- 65,68 ----
X    extern phys_bytes umap();
X    extern struct tasktab tasktab[];	/* see table.c */
X!   extern char t_stack[];		/* see table.c */
X  
X***************
X*** 79,85 ****
X     * pc, cs, and psw onto the USER's stack when starting the user the first
X!    * time.  This means that with initial sp = 0x10, user programs must leave 
X!    * the words at 0x000A, 0x000C, and 0x000E free.
X     */
X  
X!   old_state = lock();			/* we can't handle interrupts yet */
X    base_click = BASE >> CLICK_SHIFT;
X--- 77,112 ----
X     * pc, cs, and psw onto the USER's stack when starting the user the first
X!    * time.  And if an interrupt happens before the user loads a better stack
X!    * pointer, these 3 words will be used to save the state, and the interrupt
X!    * handler will use another 3, and a debugger trap may use another 3. This
X!    * means that with INIT_SP == 0x1C, user programs must leave the memory
X!    * between 0x000A and 0x001B free.
X     */
X  
X!   /* Interrupts are disabled here (by fsck.s and then redundantly by mpx88.x),
X!    * so it is unnecessary to call lock().  They are reenabled when INIT_PSW is
X!    * loaded by the first restart().
X!    */
X! 
X! #ifdef DEBUGGER
X! #ifdef DEBUG_EARLY
X!   db();
X! #endif
X! #endif
X! 
X!   /* Mask all interrupts.  BIOS calls will reenable interrupts, which hurts
X!    * if someone has hooked the vectors and Minix is copied over the handlers.
X!    */
X!   port_out(INT_CTLMASK, ~0);
X! 
X!   proc_init(); 
X!   processor = get_processor();
X!   if (processor > boot_parameters.bp_processor)
X! 	processor = boot_parameters.bp_processor;
X! #ifdef i80286
X!   prot_init();
X! #endif
X! 
X!   /* Align stack base suitably. */
X!   ktsb = ((offset_t) t_stack + (ALIGNMENT - 1)) & ~((offset_t) ALIGNMENT - 1);
X! 
X    base_click = BASE >> CLICK_SHIFT;
X***************
X*** 88,106 ****
X  
X!   for (ktsb = t_stack, t = -NR_TASKS, rp = &proc[0];
X! 		rp <= &proc[NR_TASKS+LOW_USER];  rp++, t++) {
X! 	for (i = 0; i < NR_REGS; i++) rp->p_reg[i] = 0100 * i;	/* debugging */
X  	if (t < 0) {
X  		stack_size = tasktab[t+NR_TASKS].stksize;
X! 		ktsb += stack_size / sizeof (int);
X! 		rp->p_sp = ktsb;
X! 		rp->p_splimit = ktsb - (stack_size - SAFETY) / sizeof(int);
X  	} else {
X! 		rp->p_sp = INIT_SP;
X! 		rp->p_splimit = rp->p_sp;
X  	}
X- 	rp->p_pcpsw.pc = tasktab[t + NR_TASKS].initial_pc;
X- 	if (rp->p_pcpsw.pc != 0 || t >= 0) ready(rp);
X- 	rp->p_pcpsw.psw = INIT_PSW;
X- 	rp->p_flags = 0;
X  
X  	/* Set up memory map for tasks and MM, FS, INIT. */
X--- 115,135 ----
X  
X!   for (rp = BEG_PROC_ADDR; rp <= BEG_USER_ADDR; ++rp, ++t)
X!   {
X! 	t = proc_number(rp);
X! 
X  	if (t < 0) {
X  		stack_size = tasktab[t+NR_TASKS].stksize;
X! 		rp->p_splimit = ktsb + SAFETY;
X! 		ktsb += stack_size;
X! 		rp->p_reg.r16.sp = ktsb;
X  	} else {
X! 		rp->p_reg.r16.sp = INIT_SP;
X! 		rp->p_splimit = rp->p_reg.r16.sp;
X  	}
X  
X+ 	rp->p_reg.r16.pc = (u16_t) tasktab[t + NR_TASKS].initial_pc;
X+ 	if (!isidlehardware(t)) lockready(rp);	/* IDLE, HARDWARE neveready */
X+ 	rp->p_reg.r16.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;
X+ 	rp->p_flags = 0;
X+ 
X  	/* Set up memory map for tasks and MM, FS, INIT. */
X***************
X*** 108,119 ****
X  		/* I/O tasks. */
X! 		rp->p_map[T].mem_len  = VERY_BIG; 
X  		rp->p_map[T].mem_phys = base_click;
X! 		rp->p_map[D].mem_len  = VERY_BIG; 
X  		rp->p_map[D].mem_phys = base_click + sizes[0];
X- 		rp->p_map[S].mem_len  = VERY_BIG; 
X  		rp->p_map[S].mem_phys = base_click + sizes[0] + sizes[1];
X! 		rp->p_map[S].mem_vir = sizes[0] + sizes[1];
X  	} else {
X  		/* MM, FS, and INIT. */
X! 		previous_base = proc[NR_TASKS + t - 1].p_map[S].mem_phys;
X  		rp->p_map[T].mem_len  = sizes[2*t + 2];
X--- 137,147 ----
X  		/* I/O tasks. */
X! 		rp->p_map[T].mem_len  = sizes[0];
X  		rp->p_map[T].mem_phys = base_click;
X! 		rp->p_map[D].mem_len  = sizes[1];
X  		rp->p_map[D].mem_phys = base_click + sizes[0];
X  		rp->p_map[S].mem_phys = base_click + sizes[0] + sizes[1];
X! 		rp->p_map[S].mem_vir = sizes[1];
X  	} else {
X  		/* MM, FS, and INIT. */
X! 		previous_base = proc_addr(t - 1)->p_map[S].mem_phys;
X  		rp->p_map[T].mem_len  = sizes[2*t + 2];
X***************
X*** 128,133 ****
X  #ifdef i8088
X! 	rp->p_reg[CS_REG] = rp->p_map[T].mem_phys;
X! 	rp->p_reg[DS_REG] = rp->p_map[D].mem_phys;
X! 	rp->p_reg[SS_REG] = rp->p_map[D].mem_phys;
X! 	rp->p_reg[ES_REG] = rp->p_map[D].mem_phys;
X  #endif
X--- 156,158 ----
X  #ifdef i8088
X! 	alloc_segments(rp);
X  #endif
X***************
X*** 135,144 ****
X  
X-   proc[NR_TASKS+(HARDWARE)].p_sp = k_stack;
X-   proc[NR_TASKS+(HARDWARE)].p_sp += K_STACK_BYTES/sizeof (int);
X-   proc[NR_TASKS+(HARDWARE)].p_splimit = k_stack;
X-   proc[NR_TASKS+(HARDWARE)].p_splimit += SAFETY/sizeof (int);
X- 
X-   for (rp = proc_addr(LOW_USER+1); rp < proc_addr(NR_PROCS); rp++)
X- 	rp->p_flags = P_SLOT_FREE;
X- 
X    /* Determine if display is color or monochrome and CPU type (from BIOS). */
X--- 160,161 ----
X***************
X*** 146,148 ****
X    ega = get_ega();
X!   t = (int)get_byte(CPU_TY1, CPU_TY2) & 0xFF;	/* is this PC, XT, AT ... ? */
X    if (t == PC_AT) pc_at = TRUE;
X--- 163,165 ----
X    ega = get_ega();
X!   t = get_phys_byte(((phys_bytes) CPU_TY1 << HCLICK_SHIFT) + CPU_TY2);
X    if (t == PC_AT) pc_at = TRUE;
X***************
X*** 150,153 ****
X  
X    /* Save the old interrupt vectors. */
X!   phys_b = umap(proc_addr(HARDWARE), D, (vir_bytes) vec_table, VECTOR_BYTES);
X    phys_copy(0L, phys_b, (long) VECTOR_BYTES);	/* save all the vectors */
X--- 167,173 ----
X  
X+   /* Get memory sizes from the BIOS. */
X+   mem_init();
X+ 
X    /* Save the old interrupt vectors. */
X!   phys_b = umap(proc_addr(SYSTASK), D, (vir_bytes) vec_table, VECTOR_BYTES);
X    phys_copy(0L, phys_b, (long) VECTOR_BYTES);	/* save all the vectors */
X***************
X*** 173,175 ****
X  	set_vec(AT_WINI_VECTOR, wini_int, base_click);
X- 	phys_copy(phys_b + 4L*EM_VEC, 4L*EM_VEC, 4L);	/* extended mem vec */
X    } else
X--- 193,194 ----
X***************
X*** 182,188 ****
X    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);
X  
X!   bill_ptr = proc_addr(HARDWARE);	/* it has to point somewhere */
X!   pick_proc();
X  
X!   /* Mask out interupts except ptr, disk, clock, keyboard, PIC */
X    if (ps) {
X--- 201,224 ----
X    set_vec( (BASE - 4)/4, proc, (phys_clicks) 0);
X+   
X+   bill_ptr = cproc_addr(IDLE);  /* it has to point somewhere */
X+   lockpick_proc();
X  
X! #ifdef DEBUGGER
X!   dbinit();
X! #endif
X  
X!   /* Patch assembler modules. */
X! #ifdef i80286
X!   if (processor >= 286)
X! 	klib286_init();
X! #endif
X! 
X!   /* Finish initializing 8259 (needs pc_at). */
X!   init_8259(IRQ0_VECTOR, IRQ8_VECTOR);
X! 
X!   /* Unmask interrupts for clock, floppy, printer, hard disk.  The other
X!    * devices are (correctly) unmasked _after_ they initialize themselves.
X!    * The ethernet driver will need to unmask itself when it is fixed to
X!    * work with this kernel.
X!    */
X    if (ps) {
X***************
X*** 190,196 ****
X  	port_out(0x65, CMASK4);		/* set Planar Control Register */
X! 	port_out(INT_CTLMASK, CMASK3);
X!   } else {
X! 	port_out(INT_CTLMASK, CMASK1);	/* mask out unwanted 8259 interrupts */
X! 	port_out(INT2_MASK, CMASK2);	/* same for second intr controller */
X!   }
X  
X--- 226,236 ----
X  	port_out(0x65, CMASK4);		/* set Planar Control Register */
X! 	port_out(INT_CTLMASK,
X! 		 ~(CLOCK_MASK | XT_WINI_MASK | FLOPPY_MASK | PRINTER_MASK));
X!   } else if (pc_at) {
X! 	port_out(INT_CTLMASK,
X! 		 ~(CLOCK_MASK | CASCADE_MASK | FLOPPY_MASK | PRINTER_MASK));
X! 	port_out(INT2_MASK, ~AT_WINI_MASK);
X!   } else
X! 	port_out(INT_CTLMASK,
X! 		 ~(CLOCK_MASK | XT_WINI_MASK | FLOPPY_MASK | PRINTER_MASK));
X  
X***************
X*** 202,238 ****
X  /*===========================================================================*
X-  *                                   unexpected_int                          * 
X-  *===========================================================================*/
X- PUBLIC unexpected_int(vecnr)
X- int vecnr;				/* vector number, 0 to 15 */
X- {
X- /* A trap or interrupt has occurred that was not expected. */
X- 
X-   if (vecnr == DIVIDE_VECTOR) {
X- 	printf("Division overflow trap.  SIGILL will be sent to process.\n");
X- 	cause_sig(cur_proc, SIGILL);	/* send signal to current process */
X- 	unready(proc_addr(cur_proc));	/* deschedule current process */
X-   } else {
X- 	printf("Unexpected interrupt or trap: vector = %d.  ", vecnr);
X-   }
X-   printf("pc = 0x%x   text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
X- 					proc_ptr->p_map[D].mem_len<<4);
X- }
X- 
X- 
X- /*===========================================================================*
X-  *                                   trap                                    * 
X-  *===========================================================================*/
X- PUBLIC trap()
X- {
X- /* A trap (vector >= 16) has occurred.  It was not expected. */
X- 
X-   printf("\nUnexpected trap: vector >= 16.  ");
X-   printf("pc = 0x%x    text+data+bss = 0x%x\n",proc_ptr->p_pcpsw.pc,
X- 					proc_ptr->p_map[D].mem_len<<4);
X-   printf("This may be due to accidentally including a non-MINIX\n");
X-   printf("library routine that is trying to make a system call.\n");
X- }
X- 
X- 
X- /*===========================================================================*
X   *                                   panic                                   * 
X--- 242,243 ----
X***************
X*** 250,258 ****
X    if (*s != 0) {
X! 	printf("\nKernel panic: %s",s); 
X  	if (n != NO_NUM) printf(" %d", n);
X! 	printf("\n");
X    }
X!   printf("\nType space to reboot\n");
X    wreboot();
X- 
X  }
X--- 255,265 ----
X    if (*s != 0) {
X! 	printf("\r\nKernel panic: %s",s); 
X  	if (n != NO_NUM) printf(" %d", n);
X! 	printf("\r\n");
X    }
X!   printf("Type any key to reboot\r\n");
X! #ifdef DEBUGGER
X!   db();
X! #endif
X    wreboot();
X  }
X***************
X*** 271,275 ****
X    unsigned vec[2];
X-   unsigned u;
X    phys_bytes phys_b;
X-   extern unsigned sizes[8];
X  
X--- 278,280 ----
X***************
X*** 277,284 ****
X    vec[0] = (unsigned) addr;
X!   vec[1] = (unsigned) base_click;
X!   u = (unsigned) vec;
X  
X    /* Copy the vector into place. */
X!   phys_b = ( (phys_bytes) base_click + (phys_bytes) sizes[0]) << CLICK_SHIFT;
X!   phys_b += u;
X    phys_copy(phys_b, (phys_bytes) vec_nr*4, (phys_bytes) 4);
X--- 282,287 ----
X    vec[0] = (unsigned) addr;
X!   vec[1] = (unsigned) click_to_hclick(base_click);
X  
X    /* Copy the vector into place. */
X!   phys_b = umap(cproc_addr(SYSTASK), D, (vir_bytes) vec, 4);
X    phys_copy(phys_b, (phys_bytes) vec_nr*4, (phys_bytes) 4);
END_OF_FILE
if test 13597 -ne `wc -c <'kerneldif/main.c.cdif'`; then
    echo shar: \"'kerneldif/main.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/main.c.cdif'
fi
if test -f 'mmdif/signal.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/signal.c.cdif'\"
else
echo shar: Extracting \"'mmdif/signal.c.cdif'\" \(448 characters\)
sed "s/^X//" >'mmdif/signal.c.cdif' <<'END_OF_FILE'
X*** mm-1.3/signal.c	Wed Aug  3 21:18:04 1988
X--- mm/signal.c	Wed Mar 22 00:53:28 1989
X***************
X*** 125,127 ****
X  	if (j == SIGKILL) id = -1;	/* simulate kill -1 9 */
X! 	if ( (sig_map >> i) & 1) check_sig(id, j, SUPER_USER);
X    }
X--- 125,130 ----
X  	if (j == SIGKILL) id = -1;	/* simulate kill -1 9 */
X! 	if ( (sig_map >> i) & 1) {
X! 		check_sig(id, j, SUPER_USER);
X! 		sys_sig(proc_nr, -1, SIG_DFL);	/* tell kernel it's done */
X! 	}
X    }
END_OF_FILE
if test 448 -ne `wc -c <'mmdif/signal.c.cdif'`; then
    echo shar: \"'mmdif/signal.c.cdif'\" unpacked with wrong size!
fi
# end of 'mmdif/signal.c.cdif'
fi
echo shar: End of archive 4 \(of 10\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 5 - By Bruce Evans
Message-ID: <5267@ditmela.oz>
Date: 18 May 89 01:24:14 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1366


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 10)."
# Contents:  kerneldif/klib88.x.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:10 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/klib88.x.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/klib88.x.cdif'\"
else
echo shar: Extracting \"'kerneldif/klib88.x.cdif'\" \(39670 characters\)
sed "s/^X//" >'kerneldif/klib88.x.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/klib88.x	Mon Mar 13 04:49:00 1989
X**************
X*** 0
X--- 1,1317 -----
X+ | This file contains a number of assembly code utility routines needed by the
X+ | kernel.  They are:
X+ |
X+ |   cp_mess:	copies messages from source to destination
X+ |   lock:	disable interrupts
X+ |   restore:	restore interrupts (enable/disabled) as they were before lock()
X+ |   build_sig:	build 4 word structure pushed onto stack for signals
X+ |   csv:	procedure prolog to save the registers
X+ |   cret:	procedure epilog to restore the registers
X+ |   get_chrome:	returns 0 if display is monochrome, 1 if it is color
X+ |   get_ega:	returns 1 if display is EGA, 0 otherwise
X+ |   vid_copy:	copy data to video ram (on color display during retrace only)
X+ |   scr_up:	scroll screen a line up (in software, by copying)
X+ |   scr_down:	scroll screen a line down (in software, by copying)
X+ |   reboot:	reboot for CTRL-ALT-DEL
X+ |   wreboot:	wait for character then reboot 
X+ |   wait_retrace: waits for retrace interval, and returns int disabled
X+ |   ack_char:	acknowledge character from keyboard
X+ |   save_tty_vec: save tty interrupt vector 0x71 for PS/2
X+ 
X+ | These routines are new or totally rewritten and/or renamed compatibility
X+ | with protected mode.
X+ 
X+ |   check_mem:	check a block of memory, return the valid size
X+ |   cim_at_wini:	clear the AT winchester interrupt mask
X+ |   cim_floppy:		clear the floppy interrupt mask
X+ |   cim_printer:	clear the printer interrupt mask
X+ |   cim_xt_wini:	clear the XT winchester interrupt mask
X+ |   codeseg:	return the current code segment
X+ |   dataseg:	return the current data segment
X+ |   get_extmemsize:	ask the BIOS how much extended memory there is
X+ |   get_memsize:	ask the BIOS how much normal memory there is
X+ |   get_phys_byte:	read a byte from memory and return it
X+ |   get_processor:	return the processor type
X+ |   inportb:	read a byte from a port and return it
X+ |   phys_copy:	copy data from anywhere to anywhere in memory
X+ |   porti_out:	set a port-index pair, for hardware like 6845's
X+ |   port_read:	transfer data from (hard disk controller) port to memory
X+ |   port_write:	transfer data from memory to (hard disk controller) port
X+ |   sim_printer:	set the printer interrupt mask
X+ |   tasim_printer:	test and set the printer interrupt mask
X+ |   test_and_set:	test and set locking primitive on a word in memory
X+ |   unlock:	enable interrupts
X+ 
X+ | Phys_copy was rewritten because the old one was contorted and slow to start.
X+ | Get_phys_byte replaces get_byte, with a new interface.
X+ | Inportb is in addition to port_in, with a new interface.
X+ | Port_read/write replace dma_read/write, with a new interface.
X+ 
X+ #include "../h/const.h"
X+ #include "const.h"
X+ #include "sconst.h"
X+ #define KLIB88 .define
X+ #include "sglo.h"
X+ 
X+ .text
X+ |*===========================================================================*
X+ |*				cp_mess					     *
X+ |*===========================================================================*
X+ | This routine makes a fast copy of a message from anywhere in the address
X+ | space to anywhere else.  It also copies the source address provided as a
X+ | parameter to the call into the first word of the destination message.
X+ | It is called by:
X+ |    cp_mess(src, src_clicks, src_offset, dst_clicks, dst_offset)
X+ | where all 5 parameters are shorts (16-bits).
X+ |
X+ | Note that the message size, 'Msize' is in WORDS (not bytes) and must be set
X+ | correctly.  Changing the definition of message in the type file and not
X+ | changing it here will lead to total disaster.
X+ | This routine only preserves the registers the 'C' compiler
X+ | expects to be preserved (es, ds, si, di, sp, bp).
X+ 
X+ _cp_mess:
X+ 	push es			| save es
X+ 	push ds			| save ds
X+ 	mov bx,sp		| index off bx because machine can't use sp
X+ 	push si			| save si
X+ 	push di			| save di
X+ 
X+ 	mov	ax,12(bx)	| destination click
X+ #if HCLICK_SHIFT > CLICK_SHIFT
X+ #error /* Small click sizes are not supported (right shift will lose bits). */
X+ #endif
X+ #if HCLICK_SHIFT < CLICK_SHIFT
X+ 	movb	cl,#CLICK_SHIFT-HCLICK_SHIFT
X+ 	shl	ax,cl		| destination segment
X+ #endif
X+ 	mov	es,ax
X+ 	mov	di,14(bx)	| offset of destination message
X+ 
X+ | Be careful not to destroy ds before we're finished with the bx pointer.
X+ | We're using bx and not the more natural bp to save pushing bp.
X+ 
X+ 	mov	ax,6(bx)	| process number of sender
X+ 	mov	si,10(bx)	| offset of source message
X+ 	mov	bx,8(bx)	| source click (finished with bx as a pointer)
X+ #if HCLICK_SHIFT < CLICK_SHIFT
X+ 	shl	bx,cl		| source segment
X+ #endif
X+ 	mov	ds,bx
X+ 
X+ 	stow			| copy sender's process number to dest message
X+ 	add si,*2		| don't copy first word
X+ 	mov cx,*Msize-1		| remember, first word doesn't count
X+ 	rep			| iterate cx times to copy 11 words
X+ 	movw			| copy the message
X+ 	pop di			| restore di
X+ 	pop si			| restore si
X+ 	pop ds			| restore ds
X+ 	pop es			| restore es	
X+ 	ret			| that's all folks!
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				lock					     *
X+ |*===========================================================================*
X+ | Disable CPU interrupts.  Return old psw as function value.
X+ _lock:
X+ 	pushf			| save flags on stack
X+ 	cli			| disable interrupts
X+ 	pop ax	 		| return flags for restoration later
X+ 	ret			| return to caller
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				restore					     *
X+ |*===========================================================================*
X+ | restore enable/disable bit to the value it had before last lock.
X+ _restore:
X+ 	push bp			| save it
X+ 	mov bp,sp		| set up base for indexing
X+ 	push 4(bp)		| bp is the psw to be restored
X+ 	popf			| restore flags
X+ 	pop bp			| restore bp
X+ 	ret			| return to caller
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				build_sig				     *
X+ |*===========================================================================*
X+ |* Build a structure that is pushed onto the stack for signals.  It contains
X+ |* pc, psw, etc., and is machine dependent. The format is the same as generated
X+ |* by hardware interrupts, except that after the "interrupt", the signal number
X+ |* is also pushed.  The signal processing routine within the user space first
X+ |* pops the signal number, to see which function to call.  Then it calls the
X+ |* function.  Finally, when the function returns to the low-level signal
X+ |* handling routine, control is passed back to where it was prior to the signal
X+ |* by executing a return-from-interrupt instruction, hence the need for using
X+ |* the hardware generated interrupt format on the stack.  The call is:
X+ |*     build_sig(sig_stuff, rp, sig)
X+ 
X+ _build_sig:
X+ 	push bp			| save bp
X+ 	mov bp,sp		| set bp to sp for accessing params
X+ 	push bx			| save bx
X+ 	push si			| save si
X+ 	mov bx,4(bp)		| bx points to sig_stuff
X+ 	mov si,6(bp)		| si points to proc table entry
X+ 	mov ax,8(bp)		| ax = signal number
X+ 	mov (bx),ax		| put signal number in sig_stuff
X+ 	mov ax,PCREG(si)	| ax = signalled process' PC
X+ 	mov 2(bx),ax		| put pc in sig_stuff
X+ 	mov ax,CSREG(si)	| ax = signalled process' cs
X+ 	mov 4(bx),ax		| put cs in sig_stuff
X+ 	mov ax,PSWREG(si)	| ax = signalled process' PSW
X+ 	mov 6(bx),ax		| put psw in sig_stuff
X+ 	pop si			| restore si
X+ 	pop bx			| restore bx
X+ 	pop bp			| restore bp
X+ 	ret			| return to caller
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				csv & cret				     *
X+ |*===========================================================================*
X+ | This version of csv replaces the standard one.  It checks for stack overflow
X+ | within the kernel in a simpler way than is usually done. cret is standard.
X+ csv:
X+ 	pop bx			| bx = return address
X+ 	push bp			| stack old frame pointer
X+ 	mov bp,sp		| set new frame pointer to sp
X+ 	push di			| save di
X+ 	push si			| save si
X+ 	sub sp,ax		| ax = # bytes of local variables
X+ 	cmp sp,splimit		| has kernel stack grown too large
X+ 	jbe csv.1		| if sp is too low, panic
X+ 	jmpreg (bx)		| normal return: copy bx to program counter
X+ 
X+ csv.1:
X+ 	sub ax,ax		| zero
X+ 	mov splimit,ax		| prevent call to panic from aborting in csv
X+ 	mov bx,_proc_ptr	| update rp->p_splimit
X+ 	mov P_SPLIMIT(bx),ax	| rp->sp_limit = 0
X+ 	push P_NR(bx)		| task number
X+ 	mov ax,#stkoverrun	| stack overran the kernel stack area
X+ 	push ax			| push first parameter
X+ 	call _panic		| call is: panic(stkoverrun, task number)
X+ 	j csv.1			| this should not be necessary
X+ 
X+ cret:
X+ 	lea	sp,*-4(bp)	| set sp to point to saved si
X+ 	pop	si		| restore saved si
X+ 	pop	di		| restore saved di
X+ 	pop	bp		| restore bp
X+ 	ret			| end of procedure
X+ 
X+ |*===========================================================================*
X+ |*				get_chrome				     *
X+ |*===========================================================================*
X+ | This routine calls the BIOS to find out if the display is monochrome or 
X+ | color.  The drivers are different, as are the video ram addresses, so we
X+ | need to know.
X+ _get_chrome:
X+ 	int 0x11		| call the BIOS to get equipment type
X+ 	andb al,#0x30		| isolate color/mono field
X+ 	cmpb al,*0x30		| 0x30 is monochrome
X+ 	je getchr1		| if monochrome then go to getchr1
X+ 	mov ax,#1		| color = 1
X+ 	ret			| color return
X+ getchr1: xor ax,ax		| mono = 0
X+ 	ret			| monochrome return
X+ 
X+ |*===========================================================================*
X+ |*				get_ega  				     *
X+ |*===========================================================================*
X+ | This routine calls the BIOS to find out if the display is ega.  This
X+ | is needed because scrolling is different.
X+ _get_ega:
X+ 	movb bl,*0x10
X+ 	movb ah,*0x12
X+ 	int 0x10		| call the BIOS to get equipment type
X+ 
X+ 	cmpb bl,*0x10		| if reg is unchanged, it failed
X+ 	je notega
X+ 	mov ax,#1		| color = 1
X+ 	ret			| color return
X+ notega: xor ax,ax		| mono = 0
X+ 	ret			| monochrome return
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				vid_copy				     *
X+ |*===========================================================================*
X+ | This routine takes a string of (character, attribute) pairs and writes them
X+ | onto the screen.  For a color display, the writing only takes places during
X+ | the vertical retrace interval, to avoid displaying garbage on the screen.
X+ | The call is:
X+ |     vid_copy(buffer, videobase, offset, words)
X+ | where
X+ |     'buffer'    is a pointer to the (character, attribute) pairs
X+ |     'videobase' is 0xB800 for color and 0xB000 for monochrome displays
X+ |     'offset'    tells where within video ram to copy the data
X+ |     'words'     tells how many words to copy
X+ | if buffer is zero, the fill char (blank_color) is used
X+ 
X+ _vid_copy:
X+ 	push bp			| we need bp to access the parameters
X+ 	mov bp,sp		| set bp to sp for indexing
X+ 	push si			| save the registers
X+ 	push di			| save di
X+ 	push bx			| save bx
X+ 	push cx			| save cx
X+ 	push dx			| save dx
X+ 	push es			| save es
X+ vid.0:	mov si,4(bp)		| si = pointer to data to be copied
X+ 	mov es,6(bp)		| load es NOW: int routines may NOT ruin it
X+ 	mov di,8(bp)		| di = offset within video ram
X+ 	and di,_vid_mask	| only 4K or 16K counts
X+ 	mov cx,10(bp)		| cx = word count for copy loop
X+ 	mov dx,#0x3DA		| prepare to see if color display is retracing
X+ 
X+ 	mov bx,di		| see if copy will run off end of video ram
X+ 	add bx,cx		| compute where copy ends
X+ 	add bx,cx		| bx = last character copied + 1
X+ 	sub bx,_vid_mask	| bx = # characters beyond end of video ram
X+ 	sub bx,#1		| note: dec bx doesn't set flags properly
X+ 				| it DOES for jle!!
X+ 	jle vid.1		| jump if no overrun
X+ 	sar bx,#1		| bx = # words that don't fit in video ram
X+ 	sub cx,bx		| reduce count by overrun
X+ 
X+ vid.1:	push cx			| save actual count used for later
X+ 	testb _snow,#1		| skip vertical retrace test if no snow
X+ 	jz vid.4
X+ 
X+ |vid.2:	in			| with a color display, you can only copy to
X+ |	test al,*010		| the video ram during vertical retrace, so
X+ |	jnz vid.2		| wait for start of retrace period.  Bit 3 of
X+ vid.3:	in			| 0x3DA is set during retrace.  First wait
X+ 	testb al,*010		| until it is off (no retrace), then wait
X+ 	jz vid.3		| until it comes on (start of retrace)
X+ 
X+ vid.4:	cmp si,#0		| si = 0 means blank the screen
X+ 	je vid.7		| jump for blanking
X+ 	lock			| this is a trick for the IBM PC simulator only
X+ 	inc vidlock		| 'lock' indicates a video ram access
X+ 	rep			| this is the copy loop
X+ 	movw			| ditto
X+ 
X+ vid.5:	pop si			| si = count of words copied
X+ 	cmp bx,#0		| if bx < 0, then no overrun and we are done
X+ 	jle vid.6		| jump if everything fit
X+ 	mov 10(bp),bx		| set up residual count
X+ 	mov 8(bp),#0		| start copying at base of video ram
X+ 	cmp 4(bp),#0		| NIL_PTR means store blanks
X+ 	je vid.0		| go do it
X+ 	add si,si		| si = count of bytes copied
X+ 	add 4(bp),si		| increment buffer pointer
X+ 	j vid.0			| go copy some more
X+ 
X+ vid.6:	pop es			| restore registers
X+ 	pop dx			| restore dx
X+ 	pop cx			| restore cx
X+ 	pop bx			| restore bx
X+ 	pop di			| restore di
X+ 	pop si			| restore si
X+ 	pop bp			| restore bp
X+ 	ret			| return to caller
X+ 
X+ vid.7:	mov ax,_blank_color	| ax = blanking character
X+ 	rep			| copy loop
X+ 	stow			| blank screen
X+ 	j vid.5			| done
X+ 
X+ |*===========================================================================*
X+ |*			      wait_retrace				     *
X+ |*===========================================================================*
X+ | Wait until we're in the retrace interval.  Return locked (ints off).
X+ | But enable them during the wait.
X+ 
X+ _wait_retrace: push dx
X+ 	pushf
X+ 	mov dx,_vid_port
X+ 	or dx,#0x0A
X+ wtre.3:	sti
X+ 	nop
X+ 	nop
X+ 	cli	
X+ 	in			| 0x3DA bit 3 is set during retrace.
X+ 	testb al,*010		| Wait until it is on.
X+ 	jz wtre.3
X+ 
X+ 	pop ax	 		| return flags for restoration later
X+ 	pop dx
X+ 	ret			| return to caller
X+ 
X+ |*===========================================================================*
X+ |*				scr_up  				     *
X+ |*===========================================================================*
X+ | This routine scrolls the screen up one line
X+ | 
X+ | The call is:
X+ |     scr_up(videoseg,source,dest,count)
X+ | where
X+ |     'videoseg'	is the segment of screen memory
X+ 
X+ _scr_up:
X+ 	push bp			| we need bp to access the parameters
X+ 	mov bp,sp		| set bp to sp for indexing
X+ 	push si			| save the registers
X+ 	push di			| save di
X+ 	push cx			| save cx
X+ 	push es			| save es
X+ 	push ds			| save ds
X+ 	mov si,6(bp)		| si = pointer to data to be copied
X+ 	mov di,8(bp)		| di = offset within video ram
X+ 	mov cx,10(bp)		| cx = word count for copy loop
X+ 
X+ 	mov ax,4(bp)		| set source and target segments to videoseg
X+ 	mov ds,ax
X+ 	mov es,ax
X+ 
X+ 	rep			| this is the copy loop
X+ 	movw			| ditto
X+ 
X+ 	pop ds			| restore ds
X+ 	pop es			| restore es
X+ 	pop cx			| restore cx
X+ 	pop di			| restore di
X+ 	pop si			| restore si
X+ 	pop bp			| restore bp
X+ 	ret			| return to caller
X+ 
X+ |*===========================================================================*
X+ |*				  scr_down				     *
X+ |*===========================================================================*
X+ | This routine scrolls the screen down one line
X+ | 
X+ | The call is:
X+ |     scr_down(vidoeseg,source,dest,count)
X+ | where
X+ |     'videoseg'	is the segment of screen memory
X+ 
X+ _scr_down:
X+ 	push bp			| we need bp to access the parameters
X+ 	mov bp,sp		| set bp to sp for indexing
X+ 	push si			| save the registers
X+ 	push di			| save di
X+ 	push cx			| save cx
X+ 	push es			| save es
X+ 	push ds			| save ds
X+ 	mov si,6(bp)		| si = pointer to data to be copied
X+ 	mov di,8(bp)		| di = offset within video ram
X+ 	mov cx,10(bp)		| cx = word count for copy loop
X+ 
X+ 	mov ax,4(bp)		| set source and target segments to videoseg
X+ 	mov ds,ax
X+ 	mov es,ax
X+ 
X+ 	std			| reverse to avoid propagating 1st word
X+ 	rep			| this is the copy loop
X+ 	movw			| ditto
X+ 
X+ 	cld			| restore direction flag to known state
X+ 	pop ds			| restore ds
X+ 	pop es			| restore es
X+ 	pop cx			| restore cx
X+ 	pop di			| restore di
X+ 	pop si			| restore si
X+ 	pop bp			| restore bp
X+ 	ret			| return to caller
X+ 
X+ 
X+ |===========================================================================
X+ |                		em_xfer
X+ |===========================================================================
X+ |
X+ |  This file contains one routine which transfers words between user memory
X+ |  and extended memory on an AT or clone.  A BIOS call (INT 15h, Func 87h)
X+ |  is used to accomplish the transfer.  The BIOS call is "faked" by pushing
X+ |  the processor flags on the stack and then doing a far call through the
X+ |  saved vector table to the actual BIOS location.  An actual INT 15h would
X+ |  get a MINIX complaint from an unexpected trap.
X+ 
X+ |  This particular BIOS routine runs with interrupts off since the 80286
X+ |  must be placed in protected mode to access the memory above 1 Mbyte.
X+ |  So there should be no problems using the BIOS call, except it may take
X+ |  too long and cause interrupts to be lost.
X+ |
X+ 	.text
X+ gdt:				| Begin global descriptor table
X+ 					| Dummy descriptor
X+ 	.word 0		| segment length (limit)
X+ 	.word 0		| bits 15-0 of physical address
X+ 	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0		| access rights byte
X+ 	.word 0		| reserved
X+ 					| descriptor for GDT itself
X+ 	.word 0		| segment length (limit)
X+ 	.word 0		| bits 15-0 of physical address
X+ 	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0		| access rights byte
X+ 	.word 0		| reserved
X+ src:					| source descriptor
X+ srcsz:	.word 0		| segment length (limit)
X+ srcl:	.word 0		| bits 15-0 of physical address
X+ srch:	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0x93	| access rights byte
X+ 	.word 0		| reserved
X+ tgt:					| target descriptor
X+ tgtsz:	.word 0		| segment length (limit)
X+ tgtl:	.word 0		| bits 15-0 of physical address
X+ tgth:	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0x93	| access rights byte
X+ 	.word 0		| reserved
X+ 					| BIOS CS descriptor
X+ 	.word 0		| segment length (limit)
X+ 	.word 0		| bits 15-0 of physical address
X+ 	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0		| access rights byte
X+ 	.word 0		| reserved
X+ 					| stack segment descriptor
X+ 	.word 0		| segment length (limit)
X+ 	.word 0		| bits 15-0 of physical address
X+ 	.byte 0		| bits 23-16 of physical address
X+ 	.byte 0		| access rights byte
X+ 	.word 0		| reserved
X+ 
X+ |
X+ |
X+ |  Execute a transfer between user memory and extended memory.
X+ |
X+ |  status = em_xfer(source, dest, count);
X+ |
X+ |    Where:
X+ |       status => return code (0 => OK)
X+ |       source => Physical source address (32-bit)
X+ |       dest   => Physical destination address (32-bit)
X+ |       count  => Number of words to transfer
X+ |
X+ |
X+ |
X+ _em_xfer:
X+ 	push	bp		| Save registers
X+ 	mov	bp,sp
X+ 	push	si
X+ 	push	es
X+ 	push	cx
X+ |
X+ |  Pick up source and destination addresses and update descriptor tables
X+ |
X+ 	mov ax,4(bp)
X+ 	seg cs
X+ 	mov srcl,ax
X+ 	mov ax,6(bp)
X+ 	seg cs
X+ 	movb srch,al
X+ 	mov ax,8(bp)
X+ 	seg cs
X+ 	mov tgtl,ax
X+ 	mov ax,10(bp)
X+ 	seg cs
X+ 	movb tgth,al
X+ |
X+ |  Update descriptor table segment limits
X+ |
X+ 	mov cx,12(bp)
X+ 	mov ax,cx
X+ 	add ax,ax
X+ 	seg cs
X+ 	mov tgtsz,ax
X+ 	seg cs
X+ 	mov srcsz,ax
X+ 
X+ | The BIOS call doesn't preserve the flags!!!
X+ | Worse, it enables interrupts internally.
X+ | This mainly hurts the call from db via p_dmp() and phys_copy(), which
X+ | is only invoked for protected mode.
X+ | Disable interrupts using the interrupt controller, and save the flags.
X+ | On 386's, the extended flags and registers are destroyed.
X+ 
X+ 	in	INT_CTLMASK
X+ 	push	ax
X+ 	movb	al,#0xFF	| mask everything
X+ 	out	INT_CTLMASK
X+ 	pushf
X+ 
X+ |
X+ |  Now do actual DOS call
X+ |
X+ 	push cs
X+ 	pop es
X+ 	mov si,#gdt
X+ 	movb ah,#EM_XFER_FUNC
X+ 	pushf			| fake interrupt
X+ 	callfarptr(_vec_table+4*EM_XFER_VEC)
X+ 
X+ | Restore flags and interrupt controller.
X+ 
X+ 	popf
X+ 	pop	ax
X+ 	out	INT_CTLMASK
X+ 
X+ |
X+ |  All done, return to caller.
X+ |
X+ 
X+ 	pop	cx		| restore registers
X+ 	pop	es
X+ 	pop	si
X+ 	mov	sp,bp
X+ 	pop	bp
X+ 	ret
X+ 
X+ |*===========================================================================
X+ |*				ack_char
X+ |*===========================================================================
X+ | Acknowledge character from keyboard for PS/2
X+ 
X+ _ack_char:
X+ 	push dx
X+ 	mov dx,#0x69
X+ 	in
X+ 	xor ax,#0x10
X+ 	out
X+ 	xor ax,#0x10
X+ 	out
X+ 
X+ 	mov dx,#0x66
X+ 	movb ah,#0x10
X+ 	in
X+ 	notb ah
X+ 	andb al,ah
X+ 	out
X+ 	jmp frw1
X+ frw1:	notb ah
X+ 	orb al,ah
X+ 	out
X+ 	jmp frw2
X+ frw2:	notb ah
X+ 	andb al,ah
X+ 	out
X+ 	
X+ 	pop dx
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				save_tty_vec				     *
X+ |*===========================================================================*
X+ | Save the tty vector 0x71 (PS/2)
X+ _save_tty_vec:
X+ 	push es
X+ 	xor ax,ax
X+ 	mov es,ax
X+ 	seg es
X+ 	mov ax,452
X+ 	mov tty_vec1,ax
X+ 	seg es
X+ 	mov ax,454
X+ 	mov tty_vec2,ax
X+ 	pop es
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				reboot & wreboot			     *
X+ |*===========================================================================*
X+ | This code reboots the PC
X+ 
X+ _reboot:
X+ 	cli			| disable interrupts
X+ 	mov ax,#0x20		| re-enable interrupt controller
X+ 	out 0x20
X+ 	call _eth_stp		| stop the ethernet chip
X+ 
X+ 	cmp	_pc_at,#0
X+ 	jz	old_reboot
X+ new_reboot:
X+ 	sub	bx,bx		| phys_copy(reboot_magic, 0x472L, 2L)
X+ 	mov	ax,#2		| to stop memory test
X+ 	push	bx		| can't load ds = 0x40 in protected mode
X+ 	push	ax		| push 2L
X+ 	mov	ax,#0x472
X+ 	push	bx		| push 0x472L
X+ 	push	ax
X+ 	seg	cs
X+ 	mov	ax,kernel_ds	| need real ds not necessarily current ds
X+ 	movb	cl,#HCLICK_SHIFT  | calculate bx:ax = ax * HCLICK_SHIFT
X+ 	rol	ax,cl
X+ 	movb	bl,al
X+ 	andb	bl,#HCHIGH_MASK
X+ 	andb	al,#HCLOW_MASK
X+ 	add	ax,#reboot_magic  | then bx:ax += &reboot_magic
X+ 	adc	bx,#0
X+ 	push	bx
X+ 	push	ax
X+ 	call	_phys_copy
X+ 	movb	al,#0xFE	| complemented 0x01 bit
X+ 	out	0x64		| tells keyboard controller to reset processor
X+ 
X+ | That should do it for AT's.  A solution for PS/2's remains to be found.
X+ 
X+ old_reboot:
X+ 	call resvec		| restore the vectors in low core
X+ into_reboot:
X+ 	mov ax,#0x40
X+ 	push ds
X+ 	mov ds,ax
X+ 	mov ax,#0x1234
X+ 	mov 0x72,ax
X+ 	pop ds
X+ 	test _ps,#0xFFFF
X+ 	jnz r.1
X+ 	mov ax,#0xFFFF
X+ 	mov ds,ax
X+ 	mov ax,3
X+ 	push ax
X+ 	mov ax,1
X+ 	push ax
X+ 	reti
X+ r.1:
X+ 	mov ax,_port_65		| restore port 0x65
X+ 	mov dx,#0x65
X+ 	out
X+ 	mov dx,#0x21		| restore interrupt mask port
X+ 	mov ax,#0xBC
X+ 	out
X+ 	sti			| enable interrupts
X+ 	int 0x19		| for PS/2 call bios to reboot
X+ 
X+ _wreboot:
X+ 	cli			| disable interrupts
X+ 	mov ax,#0x20		| re-enable interrupt controller
X+ 	out 0x20
X+ 	call _eth_stp		| stop the ethernet chip
X+ 
X+ 	cmp	_pc_at,#0
X+ 	jz	old_wreboot
X+ 	call	_scan_keyboard	| ack any old input
X+ waitkey:
X+ 	in	0x64		| test this keyboard status port
X+ 	testb	al,#0x01	| this bit is set when data is ready
X+ 	jz	waitkey
X+ 	j	new_reboot
X+ 
X+ old_wreboot:
X+ 	call resvec		| restore the vectors in low core
X+ 	mov	ax,#0x70	| restore the standard interrupt bases
X+ 	push	ax
X+ 	mov	ax,#8
X+ 	push	ax
X+ 	call	_init_8259
X+ 	pop	ax
X+ 	pop	ax
X+ 	movb	al,#notop(KEYBOARD_MASK)	| allow keyboard int (only)
X+ 	out	INT_CTLMASK	| after sti in int 0x16
X+ 	xor ax,ax		| wait for character before continuing
X+ 	int 0x16		| get char
X+ 	j into_reboot
X+ 
X+ | Restore the interrupt vectors in low core.
X+ resvec:
X+ 	mov cx,#2*71
X+ 	mov si,#_vec_table
X+ 	xor di,di
X+ 	mov es,di
X+ 	rep
X+ 	movw
X+ 
X+ 	mov ax,tty_vec1		| Restore keyboard interrupt vector for PS/2
X+ 	seg es
X+ 	mov 452,ax
X+ 	mov ax,tty_vec2
X+ 	seg es
X+ 	mov 454,ax
X+ 
X+ 	ret
X+ 
X+ | Some library routines use exit, so this label is needed.
X+ | Actual calls to exit cannot occur in the kernel.
X+ | Same for .fat
X+ | Same for .trp.
X+ 
X+ .fat:
X+ .trp:
X+ _exit:	sti
X+ 	j _exit
X+ 
X+ .data
X+ vidlock:	.word 0		| dummy variable for use with lock prefix
X+ splimit:	.word 0		| stack limit for current task (kernel only)
X+ stkoverrun:	.ascii "Kernel stack overrun, task = "
X+ 		.byte 0
X+ em_bad:		.ascii "Bad call to phys_copy with extended memory, error "
X+ 		.byte 0
X+ 		.space 3	| align
X+ _vec_table:	.space VECTOR_BYTES	| storage for interrupt vectors
X+ tty_vec1:	.word 0		| storage for vector 0x71 (offset)
X+ tty_vec2:	.word 0		| storage for vector 0x71 (segment)
X+ reboot_magic:	.word 0x1234	| to stop memory test
X+ 		.space 2	| align
X+ 
X+ 	.text
X+ |*===========================================================================*
X+ |*				check_mem				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC phys_bytes check_mem(phys_bytes base, phys_bytes size);
X+ | Check a block of memory, return the valid size.
X+ | Only every 16th byte is checked.
X+ | The memory and initial size must be <= 1M for non-protected mode.
X+ | An initial size of 0 means everything.
X+ | This really should do some alias checks.
X+ 
X+ _check_mem:
X+ 	push	bp
X+ 	mov	bp,sp
X+ 	push	ds
X+ 	mov	dx,4+2(bp)	| base in dx:ax
X+ 	sub	ax,ax		| prepare for early exit
X+ 	test	dx,#notop(HCHIGH_MASK)
X+ 	jnz	cm_1exit	| can't handle bases above 1M
X+ 	mov	ax,4(bp)	| ax = base segment = base / 16 % 0x10000
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,dl
X+ 	movb	cl,#HCLICK_SHIFT
X+ 	ror	ax,cl
X+ 	mov	bx,4+4(bp)	| size in dx:bx
X+ 	mov	dx,4+4+2(bp)
X+ 	test	dx,#notop(HCHIGH_MASK)
X+ 	jz	over_cm_reduce
X+ 	movb	dl,#HCHIGH_MASK
X+ 	mov	bx,#0xFFFF
X+ over_cm_reduce:
X+ 	andb	bl,#HCLOW_MASK	| cx = size in hclicks = size / 16 % 0x10000
X+ 	orb	bl,dl
X+ 	ror	bx,cl
X+ 	mov	cx,bx
X+ 	push	cx		| save size in clicks
X+ 	mov	bx,4(bp)	| bx = base offset = base % 16
X+ 	and	bx,#OFF_MASK
X+ cm_loop:
X+ 	mov	ds,ax
X+ 	movb	dl,#TEST1PATTERN
X+ 	xchgb	dl,(bx)		| write test pattern, remember original value
X+ 	xchgb	dl,(bx)		| restore original value, read test pattern
X+ 	cmpb	dl,#TEST1PATTERN	| must agree if good real memory
X+ 	jnz	cm_exit		| if different, memory is unusable
X+ 	movb	dl,#TEST2PATTERN
X+ 	xchgb	dl,(bx)
X+ 	xchgb	dl,(bx)
X+ 	cmpb	dl,#TEST2PATTERN
X+ 	jnz	cm_exit
X+ 	inc	ax		| next segment, test for wraparound at 1M
X+ 	loopnz	cm_loop
X+ cm_exit:
X+ 	pop	ax
X+ 	sub	ax,cx		| verified size in phys_clicks
X+ cm_1exit:
X+ 	movb	dl,ah		| convert to phys_bytes in dx:ax
X+ 	movb	cl,#HCLICK_SHIFT
X+ 	shl	ax,cl
X+ 	shr	dx,cl
X+ 	and	dx,#HCHIGH_MASK
X+ 	pop	ds
X+ 	pop	bp
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				cim_at_wini				     *
X+ |*				cim_floppy				     *
X+ |*				cim_printer				     *
X+ |*				cim_xt_wini				     *
X+ |*===========================================================================*
X+ 
X+ | All these routines are meant to be called from the task level where
X+ | interrupts should not be globally disabled, so they return with interrupts
X+ | enabled.
X+ 
X+ | PUBLIC void cim_at_wini();
X+ | Clear the AT winchester interrupt mask.
X+ 
X+ _cim_at_wini:
X+ 	cli
X+ 	in	INT2_MASK
X+ 	andb	al,#notop(AT_WINI_MASK)
X+ 	out	INT2_MASK
X+ 	sti
X+ 	ret
X+ 
X+ | PUBLIC void cim_floppy();
X+ | Clear the AT winchester interrupt mask.
X+ 
X+ .define _cim_floppy
X+ _cim_floppy:
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(FLOPPY_MASK)
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	ret
X+ 
X+ | PUBLIC void cim_printer();
X+ | Clear the printer interrupt mask.
X+ 
X+ _cim_printer:
X+ 	cli
X+ 	in	INT_CTLMASK
X+ #ifdef ASLD
X+ 	andb	al,#notop(PRINTER_MASK)
X+ #else
X+ 	andb	al,#notop(PRINTER_MASK) & 0xFF
X+ #endif
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	ret
X+ 
X+ | PUBLIC void cim_xt_wini();
X+ | Clear the xt_wini interrupt mask.
X+ 
X+ _cim_xt_wini:
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(XT_WINI_MASK)
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				get_extmemsize				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void get_extmemsize();
X+ | Ask the BIOS how much extended memory there is.
X+ 
X+ _get_extmemsize:
X+ 	movb	ah,#GET_EXTMEM_FUNC
X+ 	int	GET_EXTMEM_VEC	| returns size (in K) in ax for AT's
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				get_phys_byte				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC int get_phys_byte(phys_bytes offset);
X+ | Fetch a byte from anywhere in memory.
X+ | Get_byte() was inadequate above 1MB and the segment arithmetic to set up
X+ | its arguments used the wrong CLICK_SIZE.
X+ | This and its protected mode version provide a uniform interface.
X+ 
X+ _get_phys_byte:
X+ 	pop	dx		| return addr
X+ 	pop	ax		| source addr in cx:ax
X+ 	pop	cx
X+ 	sub	sp,#4		| adjust for parameter popped
X+ 	mov	bx,ax		| bx = source offset = address % 16
X+ 	and	bx,#OFF_MASK
X+ 	andb	cl,#HCHIGH_MASK	| ds = source segment = address / 16 % 0x10000
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,cl
X+ 	movb	cl,#HCLICK_SHIFT
X+ 	ror	ax,cl
X+ 	mov	cx,ds		| save ds
X+ 	mov	ds,ax
X+ 	movb	al,(bx)		| fetch the byte
X+ 	subb	ah,ah		| zero-extend to int
X+ 	mov	ds,cx
X+ 	jmpreg	(dx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				get_memsize				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void get_memsize();
X+ | Ask the BIOS how much normal memory there is.
X+ 
X+ _get_memsize:
X+ 	int	GET_MEM_VEC	| this returns the size (in K) in ax
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				phys_copy				     *
X+ |*===========================================================================*
X+ 
X+ | PUBlIC void phys_copy( long source, long destination, long bytecount);
X+ | Copy a block of physical memory.
X+ 
X+ DESTLO	=	8
X+ DESTHI	=	10
X+ SRCLO	=	4
X+ SRCHI	=	6
X+ COUNTLO	=	12
X+ COUNTHI	=	14
X+ 
X+ _phys_copy:
X+ 	push	bp		| save only registers required by C
X+ 	mov	bp,sp		| set bp to point to source arg less 4
X+ 
X+ | check for extended memory
X+ 
X+ 	mov	ax,SRCHI(bp)
X+ 	or	ax,DESTHI(bp)
X+ 	test	ax,#EM_MASK
X+ 	jnz	to_em_xfer
X+ 
X+ 	push	si		| save si
X+ 	push	di		| save di
X+ 	push	ds		| save ds
X+ 	push	es		| save es
X+ 
X+ 	mov	ax,SRCLO(bp)	| dx:ax = source address (dx is NOT segment)
X+ 	mov	dx,SRCHI(bp)
X+ 	mov	si,ax		| si = source offset = address % 16
X+ 	and	si,#OFF_MASK
X+ |	andb	dl,#HCHIGH_MASK	| ds = source segment = address / 16 % 0x10000
X+ 				| mask is unnecessary because of EM_MASK test
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,dl		| now bottom 4 bits of dx are in ax
X+ 	movb	cl,#HCLICK_SHIFT | rotate them to the top 4
X+ 	ror	ax,cl
X+ 	mov	ds,ax
X+ 
X+ 	mov	ax,DESTLO(bp)	| dx:ax = destination addr (dx is NOT segment)
X+ 	mov	dx,DESTHI(bp)
X+ 	mov	di,ax		| di = dest offset = address % 16
X+ 	and	di,#OFF_MASK
X+ |	andb	dl,#HCHIGH_MASK	| es = dest segment = address / 16 % 0x10000
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,dl
X+ 	ror	ax,cl
X+ 	mov	es,ax
X+ 
X+ 	mov	ax,COUNTLO(bp)	| dx:ax = remaining count
X+ 	mov	dx,COUNTHI(bp)
X+ 
X+ | copy upwards (can't handle overlapped copy)
X+ 
X+ pc_loop:
X+ 	mov	cx,ax		| provisional count for this iteration
X+ 	test	ax,ax		| if count >= 0x8000, only do 0x8000 per iter
X+ 	js	pc_bigcount	| low byte already >= 0x8000
X+ 	test	dx,dx
X+ 	jz	pc_upcount	| less than 0x8000
X+ pc_bigcount:
X+ 	mov	cx,#0x8000	| use maximum count per iteration
X+ pc_upcount:
X+ 	sub	ax,cx		| update count
X+ 	sbb	dx,#0		| can't underflow, so carry clear now for rcr
X+ 	rcr	cx,#1		| count in words, carry remembers if byte
X+ 	jnc	pc_even		| no odd byte
X+ 	movb			| copy odd byte
X+ pc_even:
X+ 	rep			| copy 1 word at a time
X+ 	movw			| word copy
X+ 
X+ 	mov	cx,ax		| test if remaining count is 0
X+ 	or	cx,dx
X+ 	jnz	pc_more		| more to do
X+ 
X+ 	pop	es		| restore es
X+ 	pop	ds		| restore ds
X+ 	pop	di		| restore di
X+ 	pop	si		| restore si
X+ 	pop	bp		| restore bp
X+ 	ret			| return to caller
X+ 
X+ pc_more:
X+ 	sub	si,#0x8000	| adjust pointers so the offset doesn't
X+ 	mov	cx,ds		| overflow in the next 0x8000 bytes
X+ 	add	cx,#0x800	| pointers end up same physical location
X+ 	mov	ds,cx		| the current offsets are known >= 0x8000
X+ 	sub	di,#0x8000	| since we just copied that many
X+ 	mov	cx,es
X+ 	add	cx,#0x800
X+ 	mov	es,cx
X+ 	j	pc_loop		| start next iteration
X+ 
X+ to_em_xfer:			| source or target is above 1M, join em_xfer
X+ 	sub	bx,bx		| build error code here
X+ 	mov	ax,COUNTHI(bp)	| convert count to words
X+ 	rcr	ax,#1		| carry is clear from  previous test instruct
X+ 	rcr	COUNTLO(bp),#1
X+ 	pop	bp		| stack frame now agrees with em_xfer's
X+ 	jc	pc_panic	| count was odd
X+ 	inc	bx
X+ 	test	ax,ax
X+ 	jnz	pc_panic	| count is too big
X+ 	inc	bx
X+ 	cmp	_processor,#286
X+ 	jb	pc_panic	| not 286 or 386	
X+ 	jmp	_em_xfer
X+ 
X+ pc_panic:
X+ 	push	bx		| error code
X+ 	mov	ax,#em_bad	| string to print
X+ 	push	ax
X+ 	call	_panic
X+ pc_1panic:
X+ 	j	pc_1panic	| this should not be necessary
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				porti_out				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void porti_out(int portpair, int indexpair, int datapair);
X+ | Set a port-index pair. For hardware like 6845's.
X+ 
X+ _porti_out:
X+ 	pop	cx		| return adr
X+ 	pop	dx		| portpair
X+ 	pop	ax		| indexpair
X+ 	pop	bx		| datapair
X+ 	sub	sp,#6		| adjust for 3 parameters popped
X+ 	xchgb	ah,bl		| low byte of data in ah, high index in bl
X+ 	pushf			| don't let interrupt separate the halves
X+ 	cli			
X+ 	outw			| low index and data at once
X+ 				| (may depend on 8 bit bus & speed?)
X+ 	xchg	ax,bx		| high index in al, high byte of data in ah
X+ 	outw			| high index and data at once
X+ 	popf
X+ 	jmpreg	(cx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				port_read				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void port_read(port_t port, long destination, unsigned bytcount);
X+ | Transfer data from (hard disk controller) port to memory.
X+ 
X+ _port_read:
X+ 	push	bp
X+ 	mov	bp,sp
X+ 	push	cx
X+ 	push	dx
X+ 	push	di
X+ 	push	es
X+ 	mov	ax,4+2(bp)	| destination addr in dx:ax
X+ 	mov	dx,4+2+2(bp)
X+ 	mov	di,ax		| di = dest offset = address % 16
X+ 	and	di,#OFF_MASK
X+ 	andb	dl,#HCHIGH_MASK	| es = dest segment = address / 16 % 0x10000
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,dl
X+ 	movb	cl,#HCLICK_SHIFT
X+ 	ror	ax,cl
X+ 	mov	es,ax
X+ 
X+ 	mov	cx,4+2+4(bp)	| count in bytes
X+ 	shr	cx,#1		| count in words
X+ 	mov	dx,4(bp)	| port to read from
X+ 	rep
X+ 	insw
X+ 	pop	es
X+ 	pop	di
X+ 	pop	dx
X+ 	pop	cx
X+ 	mov	sp,bp
X+ 	pop	bp
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				port_write				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void port_write(port_t port, long source, unsigned bytcount);
X+ | Transfer data from memory to (hard disk controller) port.
X+ 
X+ _port_write:
X+ 	push	bp
X+ 	mov	bp,sp
X+ 	push	cx
X+ 	push	dx
X+ 	push	si
X+ 	push	ds
X+ 	mov	ax,4+2(bp)	| source addr in dx:ax
X+ 	mov	dx,4+2+2(bp)
X+ 	mov	si,ax		| di = source offset = address % 16
X+ 	and	si,#OFF_MASK
X+ 	andb	dl,#HCHIGH_MASK	| ds = source segment = address / 16 % 0x10000
X+ 	andb	al,#HCLOW_MASK
X+ 	orb	al,dl
X+ 	movb	cl,#HCLICK_SHIFT
X+ 	ror	ax,cl
X+ 	mov	ds,ax
X+ 	mov	cx,4+2+4(bp)	| count in bytes
X+ 	shr	cx,#1		| count in words
X+ 	mov	dx,4(bp)	| port to read from
X+ 	rep
X+ 	outsw
X+ 	pop	ds
X+ 	pop	si
X+ 	pop	dx
X+ 	pop	cx
X+ 	mov	sp,bp
X+ 	pop	bp
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				sim_printer				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void sim_printer();
X+ | Set the printer interrupt mask.
X+ | This is meant to be called from the task level, so it returns with
X+ | interrupts enabled, like cim_printer().
X+ 
X+ _sim_printer:
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	orb	al,#PRINTER_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				tasim_printer				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC int tasim_printer();
X+ | Set the printer interrupt mask, indivisibly with getting its old value.
X+ | Return old value.
X+ | Although this is meant to be called from the clock interrupt handler via
X+ | a call to pr_restart(), it returns with interrupts enabled since the
X+ | clock handler has them enabled.
X+ | This might not work for multiple processors, unlike test_and_set().
X+ 
X+ _tasim_printer:
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	movb	ah,al
X+ 	orb	al,#PRINTER_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	movb	al,ah
X+ 	and	ax,#PRINTER_MASK
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				test_and_set				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC int test_and_set( int *flag );
X+ | Set the flag to TRUE, indivisibly with getting its old value.
X+ | Return old flag.
X+ 
X+ _test_and_set:
X+ 	pop	dx
X+ 	pop	bx
X+ 	sub	sp,#2
X+ 	mov	ax,#1
X+ 	xchg	ax,(bx)
X+ 	jmpreg	(dx)
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				unlock					     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC void unlock();
X+ | Enable CPU interrupts.
X+ 
X+ _unlock:
X+ 	sti			| enable interrupts
X+ 	ret			| return to caller
X+ 
X+ 
X+ #ifndef DEBUGGER
X+ 
X+ |*===========================================================================*
X+ |*				codeseg					     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC phys_clicks codeseg();
X+ | Return the current code segment.
X+ 
X+ _codeseg:
X+ 	mov	ax,cs
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				dataseg					     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC phys_clicks dataseg();
X+ | Return the current data segment.
X+ 
X+ _dataseg:
X+ 	mov	ax,ds
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				get_processor				     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC unsigned get_processor();
X+ | Decide processor type among 8088=8086, 80188=80186, 80286, 80386.
X+ | Return 86, 186, 286 or 386.
X+ | Preserves all registers except the flags and the return register ax.
X+ 
X+ | Method:
X+ | 8088=8086 and 80188=80186 push sp as new sp, 80286 and 80386 as old sp.
X+ | All but 8088=8086 do shifts mod 32 or 16.
X+ | 386 stores 0 for the upper 8 bits of the GDT pointer in 16 bit mode,
X+ | while 286 stores 0xFF.
X+ 
X+ _get_processor:
X+ 	push	sp
X+ 	pop	ax
X+ 	cmp	ax,sp
X+ 	jz	new_processor
X+ 	push	cx
X+ 	mov	cx,#0x0120
X+ 	shlb	ch,cl		| zero tells if 86
X+ 	pop	cx
X+ 	mov	ax,#86
X+ 	jz	got_processor
X+ 	mov	ax,#186
X+ 	ret
X+ 
X+ new_processor:
X+ 	push	bp
X+ 	mov	bp,sp
X+ 	sub	sp,#6		| space for GDT ptr
X+ 	defsgdt	(-6(bp))	| save 3 word GDT ptr
X+ 	add	sp,#4		| discard 2 words of GDT ptr
X+ 	pop	ax		| top word of GDT ptr
X+ 	pop	bp
X+ 	cmpb	ah,#0		| zero only for 386
X+ 	mov	ax,#286
X+ 	jnz	got_processor
X+ 	mov	ax,#386
X+ got_processor:
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				inportb					     *
X+ |*===========================================================================*
X+ 
X+ | PUBLIC unsigned inportb( port_t port );
X+ | Read an (unsigned) byte from the i/o port  port  and return it.
X+ 
X+ _inportb:
X+ 	pop	bx
X+ 	pop	dx
X+ 	dec	sp
X+ 	dec	sp
X+ 	in
X+ 	subb	ah,ah
X+ 	jmpreg	(bx)
X+ 
X+ #endif /* DEBUGGER */
END_OF_FILE
if test 39670 -ne `wc -c <'kerneldif/klib88.x.cdif'`; then
    echo shar: \"'kerneldif/klib88.x.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/klib88.x.cdif'
fi
echo shar: End of archive 5 \(of 10\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!agate!helios.ee.lbl.gov!ncis.tis.llnl.gov!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 6 - By Bruce Evans
Message-ID: <5268@ditmela.oz>
Date: 18 May 89 01:25:04 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1404


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 10)."
# Contents:  kerneldif/memory.c.cdif kerneldif/misc.c.cdif
#   kerneldif/mpx286.x.cdif kerneldif/mpx88.x.cdif
#   kerneldif/printer.c.cdif kerneldif/table.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:16 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/memory.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/memory.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/memory.c.cdif'\" \(3714 characters\)
sed "s/^X//" >'kerneldif/memory.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/memory.c	Thu Oct  6 21:07:43 1988
X--- kernel/memory.c	Sun Mar  5 02:41:00 1989
X***************
X*** 5,6 ****
X--- 5,7 ----
X   *     /dev/ram		- RAM disk
X+  *     /dev/port	- i/o ports (i8088 only)
X   * It accepts three messages, for reading, for writing, and for
X***************
X*** 31,36 ****
X  #include "type.h"
X  #include "proc.h"
X  
X! #define NR_RAMS            4	/* number of RAM-type devices */
X! #define EM_ORIGIN   0x100000	/* origin of extended memory on the AT */
X  PRIVATE message mess;		/* message buffer */
X--- 32,41 ----
X  #include "type.h"
X+ #include "glo.h"
X  #include "proc.h"
X  
X! #ifdef i8088
X! #define NR_RAMS            5	/* number of RAM-type devices */
X! #else
X! #define NR_RAMS            4
X! #endif
X  PRIVATE message mess;		/* message buffer */
X***************
X*** 48,56 ****
X    extern unsigned sizes[8];
X!   extern phys_clicks get_base();
X  
X- 
X    /* Initialize this task. */
X!   ram_origin[KMEM_DEV] = (phys_bytes) get_base() << CLICK_SHIFT;
X!   ram_limit[KMEM_DEV] = (sizes[0] + sizes[1]) << CLICK_SHIFT;
X!   ram_limit[MEM_DEV] = MEM_BYTES;
X  
X--- 53,72 ----
X    extern unsigned sizes[8];
X!   extern phys_bytes umap();
X  
X    /* Initialize this task. */
X!   ram_origin[KMEM_DEV] = umap(cproc_addr(SYSTASK), D, (vir_bytes) 0,
X!                               (vir_bytes) 1);
X!   ram_limit[KMEM_DEV] = ((phys_bytes) sizes[1] << CLICK_SHIFT) +
X!                         ram_origin[KMEM_DEV];
X! #ifdef i8088
X!   if (processor < 286)
X! 	ram_limit[MEM_DEV] = 0x100000;
X!   else if (processor < 386)
X! 	ram_limit[MEM_DEV] = 0x1000000;
X!   else
X! 	ram_limit[MEM_DEV] = MAX_P_LONG;	/* not big enough */
X!   ram_limit[PORT_DEV] = 0x10000;
X! #else
X! #error /* memory limit not set up */
X! #endif
X  
X***************
X*** 90,97 ****
X  {
X! /* Read or write /dev/null, /dev/mem, /dev/kmem, or /dev/ram. */
X  
X!   int device, count, words, status;
X    phys_bytes mem_phys, user_phys;
X    struct proc *rp;
X-   extern phys_clicks get_base();
X    extern phys_bytes umap();
X--- 106,112 ----
X  {
X! /* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram or /dev/port. */
X  
X!   int device, count, endport, port, portval;
X    phys_bytes mem_phys, user_phys;
X    struct proc *rp;
X    extern phys_bytes umap();
X***************
X*** 115,134 ****
X  
X!   /* Copy the data. Origin above EM_ORIGIN means AT extended memory */
X!   if (ram_origin[device] < EM_ORIGIN) {
X! 	/* Ordinary case.  RAM disk is below 640K. */
X! 	if (m_ptr->m_type == DISK_READ)
X! 		phys_copy(mem_phys, user_phys, (long) count);
X! 	else
X! 		phys_copy(user_phys, mem_phys, (long) count);
X!   } else {
X! 	/* AT with RAM disk in extended memory (above 1 MB). */
X! 	if (count & 1) panic("RAM disk got odd byte count\n", NO_NUM);
X! 	words = count >> 1;	/* # words is half # bytes */
X! 	if (m_ptr->m_type == DISK_READ) {
X! 		status = em_xfer(mem_phys, user_phys, words);
X! 	} else {
X! 		status = em_xfer(user_phys, mem_phys, words);
X  	}
X! 	if (status != 0) count = -1;
X!   }	
X    return(count);
X--- 130,155 ----
X  
X! #ifdef PORT_DEV
X!   /* Do special case of /dev/port. */
X!   if (device == PORT_DEV) {
X! 	port = mem_phys;
X! 	mem_phys = umap(cproc_addr(MEM), D, (vir_bytes) &portval,
X! 	                (vir_bytes) 1);
X! 	for (endport = port + count; port != endport; ++port) {
X! 		if (m_ptr->m_type == DISK_READ) {
X! 			port_in(port, &portval);
X! 			phys_copy(mem_phys, user_phys++, (phys_bytes) 1);
X! 		} else {
X! 			phys_copy(user_phys++, mem_phys, (phys_bytes) 1);
X! 			port_out(port, portval);
X! 		}
X  	}
X! 	return(count);
X!   }
X! #endif
X! 
X!   /* Copy the data. */
X!   if (m_ptr->m_type == DISK_READ)
X! 	phys_copy(mem_phys, user_phys, (long) count);
X!   else
X! 	phys_copy(user_phys, mem_phys, (long) count);
X    return(count);
END_OF_FILE
if test 3714 -ne `wc -c <'kerneldif/memory.c.cdif'`; then
    echo shar: \"'kerneldif/memory.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/memory.c.cdif'
fi
if test -f 'kerneldif/misc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/misc.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/misc.c.cdif'\" \(2738 characters\)
sed "s/^X//" >'kerneldif/misc.c.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/misc.c	Thu Mar 23 03:15:44 1989
X***************
X*** 0 ****
X--- 1,74 ----
X+ /* This file contains a collection of miscellaneous procedures:
X+  *	mem_init:	initialize memory tables.  Some memory is reported
X+  *			by the BIOS, some is guesstimated and checked later
X+  */
X+ 
X+ #include "../h/const.h"
X+ #include "../h/type.h"
X+ #include "const.h"
X+ #include "type.h"
X+ #include "glo.h"
X+ 
X+ #ifdef i8088
X+ 
X+ #define EM_BASE     0x100000L	/* base of extended memory on AT's */
X+ #define SHADOW_BASE 0xFA0000L	/* base of RAM shadowing ROM on some AT's */
X+ #define SHADOW_MAX  0x060000L	/* maximum usable shadow memory (16M limit) */
X+ 
X+ extern unsigned get_extmemsize();
X+ extern unsigned get_memsize();
X+ 
X+ 
X+ /*=========================================================================*
X+  *				mem_init				   *
X+  *=========================================================================*/
X+ PUBLIC mem_init()
X+ {
X+ /* Initialize the memory size tables.  This is complicated by fragmentation
X+  * and different access strategies for protected mode.  There must be a
X+  * chunk at 0 big enough to hold Minix proper.  For 286 and 386 processors,
X+  * there can be extended memory (memory above 1MB).  This usually starts at
X+  * 1MB, but there may be another chunk just below 16MB, reserved under DOS
X+  * for shadowing ROM, but available to Minix if the hardware can be re-mapped.
X+  * In protected mode, extended memory is accessible assuming CLICK_SIZE is
X+  * large enough, and is treated as ordinary momory.
X+  * The magic bits for memory types are:
X+  *	1: extended
X+  *	0x80: must be checked since BIOS doesn't and it may not be there.
X+  */
X+ 
X+   /* Get the size of ordinary memory from the BIOS. */
X+   memsize[0] = k_to_click(get_memsize());	/* 0 base and type */
X+ 
X+ #ifdef SPARE_VIDEO_MEMORY
X+   /* Spare video memory.  Experimental, it's too slow for program memory
X+    * except maybe on PC's, and belongs low in a memory hierarchy.
X+    */
X+   if (color) {
X+ 	memsize[1] = MONO_SIZE >> CLICK_SHIFT;
X+ 	membase[1] = MONO_BASE >> CLICK_SHIFT;
X+   } else {
X+ 	memsize[1] = COLOR_SIZE >> CLICK_SHIFT;
X+ 	membase[1] = COLOR_BASE >> CLICK_SHIFT;
X+   }
X+   memtype[1] = 0x80;
X+ #endif
X+ 
X+   if (pc_at) {
X+ 	/* Get the size of extended memory from the BIOS.  This is special
X+ 	 * except in protected mode, but protected mode is now normal.
X+ 	 */
X+ 	memsize[2] = k_to_click(get_extmemsize());
X+ 	membase[2] = EM_BASE >> CLICK_SHIFT;
X+ 
X+ 	/* Shadow ROM memory. */
X+ 	memsize[3] = SHADOW_MAX >> CLICK_SHIFT;
X+ 	membase[3] = SHADOW_BASE >> CLICK_SHIFT;
X+ 	memtype[3] = 0x80;
X+ 	if (processor < 286) {
X+ 		memtype[2] = 1;
X+ 		memtype[3] |= 1;
X+ 	}
X+   }
X+ }
X+ #endif /* i8088 */
END_OF_FILE
if test 2738 -ne `wc -c <'kerneldif/misc.c.cdif'`; then
    echo shar: \"'kerneldif/misc.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/misc.c.cdif'
fi
if test -f 'kerneldif/mpx286.x.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/mpx286.x.cdif'\"
else
echo shar: Extracting \"'kerneldif/mpx286.x.cdif'\" \(7400 characters\)
sed "s/^X//" >'kerneldif/mpx286.x.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/mpx286.x	Mon Mar 13 05:03:23 1989
X***************
X*** 0 ****
X--- 1,262 ----
X+ |*===========================================================================*
X+ |*			mpx support for 286 protected mode		     *
X+ |*===========================================================================*
X+ 
X+ #include "const.h"
X+ #include "protect.h"
X+ #include "sconst.h"
X+ #define MPX286 .define
X+ #include "sglo.h"
X+ 
X+ 	.text
X+ |*===========================================================================*
X+ |*				exception handlers			     *
X+ |*===========================================================================*
X+ 
X+ _divide_error:
X+ 	pushi8	(DIVIDE_VECTOR)
X+ 	j	pexception
X+ 
X+ _nmi:
X+ 	pushi8	(NMI_VECTOR)
X+ 	j	pexception
X+ 
X+ _overflow:
X+ 	pushi8	(OVERFLOW_VECTOR)
X+ 	j	pexception
X+ 
X+ _bounds_check:
X+ 	pushi8	(BOUNDS_VECTOR)
X+ 	j	pexception
X+ 
X+ _inval_opcode:
X+ 	pushi8	(INVAL_OP_VECTOR)
X+ 	j	pexception
X+ 
X+ _copr_not_available:
X+ 	pushi8	(COPROC_NOT_VECTOR)
X+ 	j	pexception
X+ 
X+ _double_fault:
X+ 	pushi8	(DOUBLE_FAULT_VECTOR)
X+ 	j	perrexception
X+ 
X+ _copr_seg_overrun:
X+ 	pushi8	(COPROC_SEG_VECTOR)
X+ 	j	pexception
X+ 
X+ _inval_tss:
X+ 	pushi8	(INVAL_TSS_VECTOR)
X+ 	j	perrexception
X+ 
X+ _segment_not_present:
X+ 	pushi8	(SEG_NOT_VECTOR)
X+ 	j	perrexception
X+ 
X+ _stack_exception:
X+ 	pushi8	(STACK_FAULT_VECTOR)
X+ 	j	perrexception
X+ 
X+ _general_protection:
X+ 	pushi8	(PROTECTION_VECTOR)
X+ 	j	perrexception
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				pexception				     *
X+ |*===========================================================================*
X+ 
X+ | This is called for all exceptions which don't push an error code.
X+ 
X+ pexception:
X+ 	seg	ss
X+ 	pop	ds_ex_number
X+ 	call	p2_save
X+ 	j	p1exception
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				perrexception				     *
X+ |*===========================================================================*
X+ 
X+ | This is called for all exceptions which push an error code.
X+ 
X+ p2_errexception:
X+ perrexception:
X+ 	seg	ss
X+ 	pop	ds_ex_number
X+ 	seg	ss
X+ 	pop	trap_errno
X+ 	call	p2_save
X+ p1exception:			| Common for all exceptions.
X+ 	push	ds_ex_number
X+ 	call	_exception
X+ 	add	sp,#2
X+ 	cli
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p2_save					     *
X+ |*===========================================================================*
X+ 
X+ | Save for 286 protected mode.
X+ | This is much simpler than for 8086 mode, because the stack already points
X+ | into process table, or has already been switched to the kernel stack.
X+ 
X+ p2_save:
X+ 	cld			| set direction flag to a known value
X+ 	pusha			| save "general" registers
X+ 	push	ds		| save ds
X+ 	push	es		| save es
X+ 	mov	dx,ss		| ss is kernel data segment
X+ 	mov	ds,dx		| load rest of kernel segments
X+ 	mov	es,dx
X+ 	movb	al,#ENABLE	| reenable int controller
X+ 	out	INT_CTL
X+ 	mov	bp,sp		| prepare to return
X+ 	incb	_k_reenter	| from -1 if not reentering
X+ 	jnz	set_p1restart	| stack is already kernel's
X+ 	mov	sp,#k_stktop
X+ #ifdef SPLIMITS
X+ 	mov	splimit,#k_stack+8
X+ #endif
X+ 	pushi16	(prestart)	| build return address for interrupt handler
X+ 	jmpmem	(RETADR-P_STACKBASE(bp))
X+ 
X+ set_p1restart:
X+ 	pushi16	(p1restart)
X+ 	jmpmem	(RETADR-P_STACKBASE(bp))
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p2_s_call				     *
X+ |*===========================================================================*
X+ 
X+ _p2_s_call:
X+ 	cld			| set direction flag to a known value
X+ 	sub	sp,#6*2		| skip RETADR, ax, cx, dx, bx, st
X+ 	push	bp		| stack already points into process table
X+ 	push	si
X+ 	push	di
X+ 	push	ds
X+ 	push	es
X+ 	mov	dx,ss
X+ 	mov	ds,dx
X+ 	mov	es,dx
X+ 	incb	_k_reenter
X+ 	mov	si,sp		| assumes P_STACKBASE == 0
X+ 	mov	sp,#k_stktop
X+ #ifdef SPLIMTS
X+ 	mov	splimit,#k_stack+8
X+ #endif
X+ 				| end of inline save
X+ 	sti			| allow SWITCHER to be interrupted
X+ 				| now set up parameters for C routine sys_call
X+ 	push	bx		| pointer to user message
X+ 	push	ax		| src/dest
X+ 	push	cx		| SEND/RECEIVE/BOTH
X+ 	call	_sys_call	| sys_call(function, src_dest, m_ptr)
X+ 				| caller is now explicitly in proc_ptr
X+ 	mov	AXREG(si),ax	| sys_call MUST PRESERVE si
X+ 	cli
X+ 
X+ | Fall into code to restart proc/task running.
X+ 
X+ prestart:
X+ 
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+ 	cmp	_held_head,#0	| do fast test to usually avoid function call
X+ 	jz	over_call_unhold
X+ 	call	_unhold		| this is rare so overhead is acceptable
X+ over_call_unhold:
X+ 	mov	si,_proc_ptr
X+ #ifdef SPLIMITS
X+ 	mov	ax,P_SPLIMIT(si)	| splimit = p_splimit
X+ 	mov	splimit,ax
X+ #endif
X+ 	deflldt	(P_LDT_SEL(si))		| enable task's segment descriptors
X+ 	defsldt	(_tss+TSS2_S_LDT)
X+ 	lea	ax,P_STACKTOP(si)	| arrange for next interrupt
X+ 	mov	_tss+TSS2_S_SP0,ax	| to save state in process table
X+ 	mov	sp,si		| assumes P_STACKBASE == 0
X+ p1restart:
X+ 	decb	_k_reenter
X+ 	pop	es
X+ 	pop	ds
X+ 	popa
X+ 	add	sp,#2		| skip RETADR
X+ 	iret			| continue process
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				p_restart				     *
X+ |*===========================================================================*
X+ 
X+ | This now just starts the 1st task.
X+ 
X+ p_restart:
X+ 
X+ | Call the BIOS to switch to protected mode.
X+ | This is just to do any cleanup necessary, typically to disable a hardware
X+ | kludge which holds the A20 address line low.
X+ 
X+ | The call requires the gdt as we set it up:
X+ |	gdt pointer in gdt[1]
X+ |	ldt pointer in gdt[2]
X+ |	new ds in gdt[3]
X+ |	new es in gdt[4]
X+ |	new ss in gdt[5]
X+ |	new cs in gdt[6]
X+ |	nothing in gdt[7] (overwritten with BIOS cs)
X+ |	ICW2 for master 8259 in bh
X+ |	ICW2 for slave 8259 in bl
X+ | Interrupts are enabled at the start but at the finish they are disabled in
X+ | both the processor flags and the interrupt controllers. Most registers are
X+ | destroyed. The 8259's are reinitialised.
X+ 
X+ 	in	INT_CTLMASK	| save interrupt masks
X+ 	push	ax
X+ 	in	INT2_MASK
X+ 	push	ax
X+ 	movb	al,#0xFF	| protect against sti in BIOS
X+ 	out	INT_CTLMASK
X+ 	mov	si,#_gdt
X+ 	mov	bx,#IRQ0_VECTOR * 256 orop IRQ8_VECTOR
X+ 	movb	ah,#SET_PROTECT_FUNC
X+ 	pushf
X+ 	callfarptr(_vec_table+4*SET_PROTECT_VEC)
X+ 	pushi8	(0)		| set kernel flags to known state, especially
X+ 	popf			| clear nested task and interrupt enable
X+ 	pop	ax		| restore interrupt masks
X+ 	out	INT2_MASK
X+ 	pop	ax
X+ 	out	INT_CTLMASK
X+ 
X+ 	deflidt	(_gdt+IDT_SELECTOR)	| loaded by BIOS, but in wrong mode!
X+ 	mov	ax,#TSS_SELECTOR	| no other TSS is used except by db
X+ 	defltrax
X+ 	sub	ax,ax		| zero, for no PRESENT bit
X+ 	movb	_gdt+GDT_SELECTOR+DESC_ACCESS,al	| zap invalid desc.
X+ 	movb	_gdt+IDT_SELECTOR+DESC_ACCESS,al
X+ 	movb	_gdt+BIOS_CS_SELECTOR+DESC_ACCESS,al
X+ 
X+ p2_resdone:
X+ 	jmp	prestart
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				data					     *
X+ |*===========================================================================*
X+ 
X+ 	.bss
X+ 
X+ ds_ex_number:
X+ 	.space	2
X+ 	.space	2		| align
X+ trap_errno:
X+ 	.space	4		| large enough for mpx386 too
END_OF_FILE
if test 7400 -ne `wc -c <'kerneldif/mpx286.x.cdif'`; then
    echo shar: \"'kerneldif/mpx286.x.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/mpx286.x.cdif'
fi
if test -f 'kerneldif/mpx88.x.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/mpx88.x.cdif'\"
else
echo shar: Extracting \"'kerneldif/mpx88.x.cdif'\" \(16900 characters\)
sed "s/^X//" >'kerneldif/mpx88.x.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/mpx88.x	Thu Mar 23 01:21:54 1989
X**************
X*** 0
X--- 1,589 -----
X+ | This file is part of the lowest layer of the MINIX kernel.  The other parts
X+ | are "proc.c" and protected mode version(s) of this file.  The lowest layer
X+ | does process switching and message handling.
X+ 
X+ | Every transition to the kernel goes through this file (or a protected mode
X+ | version).  Transitions are caused by sending/receiving messages and by most
X+ | interrupts.  (RS232 interrupts may be handled in the file "rs2.x" and then
X+ | they rarely enter the kernel.)
X+ 
X+ | Transitions to the kernel may be nested.  The initial entry may be with a
X+ | system call, exception or hardware interrupt; reentries may only be made
X+ | by hardware interrupts.  The count of reentries is kept in 'k_reenter'.
X+ | It is important for deciding whether to switch to the kernel stack and
X+ | for protecting the message passing code in "proc.c".
X+ 
X+ | For the message passing trap, most of the machine state is saved in the
X+ | proc table.  (Some of the registers need not be saved.)  Then the stack is
X+ | switched to 'k_stack', and interrupts are reenabled.  Finally, the system
X+ | call handler (in C) is called.  When it returns, interrupts are disabled
X+ | again and the code falls into the restart routine, to finish off held-up
X+ | interrupts and run the process or task whose pointer is in 'proc_ptr'.
X+ 
X+ | Hardware interrupt handlers do the same, except  (1) The entire state must
X+ | be saved.  (2) There are too many handlers to do this inline, so the save
X+ | routine is called.  A few cycles are saved by pushing the address of the
X+ | appropiate restart routine for a return later.  (3) A stack switch is
X+ | avoided when the stack is already switched.  (4) The (master) 8259 interrupt
X+ | controller is reenabled centrally in save().  (5) Each interrupt handler
X+ | masks its interrupt line using the 8259 before enabling (other unmasked)
X+ | interrupts, and unmasks it after servicing the interrupt.  This limits the
X+ | nest level to the number of lines and protects the handler from itself.
X+ 
X+ | The external entry points into this file are:
X+ |   s_call:	process or task wants to send or receive a message
X+ |   tty_int:	interrupt routine for each key depression and release
X+ |   rs232_int:	interrupt routine for each rs232 interrupt on port 1
X+ |   secondary_int:	interrupt routine for each rs232 interrupt on port 2
X+ |   lpr_int:	interrupt routine for each line printer interrupt
X+ |   disk_int:	disk interrupt routine
X+ |   wini_int:	winchester interrupt routine
X+ |   clock_int:	clock interrupt routine (HZ times per second)
X+ |   eth_int:	ethernet interrupt routine
X+ |   int00-int16:handlers for unused interrupt vectors < 17
X+ |   trp:	all traps with vector >= 16 are vectored here
X+ |   restart:	start running a task or process
X+ |   idle_task:	executed when there is no work
X+ 
X+ | and for protected mode to patch
X+ |   save:	save the machine state in the proc table
X+ 
X+ | and for protected mode with C RS232 handlers, some duplicate labels to
X+ | avoid #if's elsewhere:
X+ |   prs232_int:	duplicate rs232_int
X+ |   psecondary_int:	duplicate secondary_int
X+ 
X+ #include "../h/const.h"
X+ #include "../h/com.h"
X+ #include "const.h"
X+ #include "sconst.h"
X+ #define MPX88 .define
X+ #include "sglo.h"
X+ 
X+ 	.text
X+ 
X+ begtext:
X+ |*===========================================================================*
X+ |*				MINIX					     *
X+ |*===========================================================================*
X+ MINIX:				| this is the entry point for the MINIX kernel.
X+ 	j	over_kernel_ds	| skip over the next few bytes
X+ 	.word	CLICK_SHIFT	| for build, later used by db for syms offset
X+ kernel_ds:
X+ 	.word	0		| build puts kernel DS here at fixed address 4
X+ over_kernel_ds:
X+ 	cli                     | disable interrupts
X+ 	cld			| C compiler needs es = ds and direction = up
X+ 
X+ | this cli is redundant, fsck1.s already did it
X+ | NB stack is invalid here - fsck1.s did the wrong things
X+ 
X+ | copy boot parameters to kernel data, if any
X+ 
X+ 	seg	cs
X+ 	mov	es,kernel_ds
X+ 	test	ax,ax		| 0 for new boot, nonzero (scan code) for old
X+ 	jnz	over_cp_param	| skip copying parameters if old boot
X+ 	seg	es
X+ 	mov	dx,_sizeof_bparam
X+ 	cmp	cx,dx
X+ 	jle	over_adjust_param_count
X+ 	mov	cx,dx
X+ over_adjust_param_count:
X+ 	mov	ds,di		| ds:si = parameters source
X+ 	mov	di,#_boot_parameters	| es:di = parameters target
X+ 	rep
X+ 	movb
X+ over_cp_param:
X+ 	mov	ax,es
X+ 	mov	ds,ax		| ds now contains proper value
X+ 	mov	ss,ax		| ss now contains proper value
X+ 	mov	_scan_code,bx	| save scan code from bootstrap
X+ 	mov	sp,#k_stktop	| set sp to point to the top of kernel stack
X+ 	jmp	_main		| start the main program of MINIX
X+ 				| this should return by calling restart()
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				tty_int					     *
X+ |*===========================================================================*
X+ _tty_int:			| Interrupt routine for terminal input.
X+ 	call	save		| save the machine state
X+ 	in	INT_CTLMASK	| mask out further keyboard interrupts
X+ 	orb	al,#KEYBOARD_MASK
X+ 	out	INT_CTLMASK
X+ 	sti			| allow unmasked, non-keyboard, interrupts
X+ 	call	_keyboard	| process a keyboard interrupt
X+ 	cli
X+ 	in	INT_CTLMASK	| unmask keyboard interrupt
X+ 	andb	al,#notop(KEYBOARD_MASK)
X+ 	out	INT_CTLMASK
X+ 	ret			| return to appropiate restart built by save()
X+ 
X+ 
X+ #ifdef C_RS232_INT_HANDLERS
X+ |*===========================================================================*
X+ |*				rs232_int				     *
X+ |*===========================================================================*
X+ _rs232_int:			| Interrupt routine for rs232 I/O.
X+ #ifdef i80286
X+ _prs232_int:
X+ #endif
X+ 	call	save
X+ 	in	INT_CTLMASK
X+ 	orb	al,#RS232_MASK
X+ 	out	INT_CTLMASK
X+ 
X+ | Don't enable interrupts, the handlers are not designed for it.
X+ | The mask was set as usual so the handler can reenable interrupts as desired.
X+ 
X+ 	call	_rs232_1handler	| process a serial line 1 interrupt
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(RS232_MASK)
X+ 	out	INT_CTLMASK
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				secondary_int				     *
X+ |*===========================================================================*
X+ _secondary_int:			| Interrupt routine for rs232 port 2
X+ #ifdef i80286
X+ _psecondary_int:
X+ #endif
X+ 	call	save
X+ 	in	INT_CTLMASK
X+ 	orb	al,#SECONDARY_MASK
X+ 	out	INT_CTLMASK
X+ 	call	_rs232_2handler	| process a serial line 2 interrupt
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(SECONDARY_MASK)
X+ 	out	INT_CTLMASK
X+ 	ret
X+ #endif /* C_RS232_INT_HANDLERS */
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				lpr_int					     *
X+ |*===========================================================================*
X+ _lpr_int:			| Interrupt routine for printer output.
X+ 	call	save
X+ 	in	INT_CTLMASK
X+ 	orb	al,#PRINTER_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	call	_pr_char	| process a line printer interrupt
X+ 	cli
X+ 	in	INT_CTLMASK
X+ #ifdef ASLD
X+ 	andb	al,#notop(PRINTER_MASK)
X+ #else
X+ 	andb	al,#notop(PRINTER_MASK) & 0xFF
X+ #endif
X+ 	out	INT_CTLMASK
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				disk_int				     *
X+ |*===========================================================================*
X+ _disk_int:			| Interrupt routine for the floppy disk.
X+ 	call	save
X+ 	cmp	_ps,#0		| check for 2nd int controller on ps (?)
X+ 	je	over_ps_disk
X+ 	movb	al,#ENABLE
X+ 	out	0x3C
X+ over_ps_disk:
X+ 
X+ | The last doesn't make sense as an 8259 command, since the floppy vector
X+ | seems to be the same on PS's so the usual 8259 must be controlling it.
X+ | This used to be done at the start of the interrupt handler, in proc.c.
X+ | Find out where it really goes, and if there are any mask bits in port
X+ | 0x3D which have to be fiddled (here and in fdc_results()).
X+ 
X+ 	in	INT_CTLMASK
X+ 	orb	al,#FLOPPY_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	mov	ax,#FLOPPY
X+ 	push	ax
X+ 	call	_interrupt	| interrupt(FLOPPY)
X+ 	add	sp,#2
X+ 	cli
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				wini_int				     *
X+ |*===========================================================================*
X+ _wini_int:			| Interrupt routine for the winchester disk.
X+ 	call	save
X+ 	cmp	_pc_at,#0	| check for 2nd int controller on AT
X+ 	jnz	at_wini_int
X+ 
X+ xt_wini_int:
X+ 	in	INT_CTLMASK
X+ 	orb	al,#XT_WINI_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	mov	ax,#WINCHESTER
X+ 	push	ax
X+ 	call	_interrupt	| interrupt(WINCHESTER)
X+ 	add	sp,#2
X+ 	cli
X+ 	ret
X+ 
X+ at_wini_int:
X+ 	in	INT2_MASK
X+ 	orb	al,#AT_WINI_MASK
X+ 	out	INT2_MASK
X+ 	sti
X+ 	movb	al,#ENABLE	| reenable slave 8259
X+ 	out	INT2_CTL	| the master one was done in save() as usual
X+ 	mov	ax,#WINCHESTER
X+ 	push	ax
X+ 	call	_interrupt	| interrupt(WINCHESTER)
X+ 	add	sp,#2
X+ 	cli
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				clock_int				     *
X+ |*===========================================================================*
X+ _clock_int:			| Interrupt routine for the clock.
X+ 	call	save
X+ 	in	INT_CTLMASK
X+ 	orb	al,#CLOCK_MASK
X+ 	out	INT_CTLMASK
X+ 	sti
X+ 	call	_clock_handler	| process a clock interrupt
X+ 				| This calls interrupt() only if necessary.
X+ 				| Very rarely.
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(CLOCK_MASK)
X+ 	out	INT_CTLMASK
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				eth_int					     *
X+ |*===========================================================================*
X+ _eth_int:			| Interrupt routine for ethernet input
X+ 	call	save
X+ 	in	INT_CTLMASK
X+ 	orb	al,#ETHER_MASK
X+ 	out	INT_CTLMASK
X+ 	sti			| may not be able to handle this
X+ 				| but ethernet doesn't work in protected mode
X+ 				| yet, and tacitly assumes CLICK_SIZE == 16
X+ 	call	_dp8390_int	| call the handler
X+ 	cli
X+ 	in	INT_CTLMASK
X+ 	andb	al,#notop(ETHER_MASK)
X+ 	out	INT_CTLMASK
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				int00-16				     *
X+ |*===========================================================================*
X+ _int00:				| interrupt through vector 0
X+ 	push	ax
X+ 	movb	al,#0
X+ 	j	exception
X+ 
X+ _int01:				| interrupt through vector 1, etc
X+ 	push	ax
X+ 	movb	al,#1
X+ 	j	exception
X+ 
X+ _int02:
X+ 	push	ax
X+ 	movb	al,#2
X+ 	j	exception
X+ 
X+ _int03:
X+ 	push	ax
X+ 	movb	al,#3
X+ 	j	exception
X+ 
X+ _int04:
X+ 	push	ax
X+ 	movb	al,#4
X+ 	j	exception
X+ 
X+ _int05:
X+ 	push	ax
X+ 	movb	al,#5
X+ 	j	exception
X+ 
X+ _int06:
X+ 	push	ax
X+ 	movb	al,#6
X+ 	j	exception
X+ 
X+ _int07:
X+ 	push	ax
X+ 	movb	al,#7
X+ 	j	exception
X+ 
X+ _int08:
X+ 	push	ax
X+ 	movb	al,#8
X+ 	j	exception
X+ 
X+ _int09:
X+ 	push	ax
X+ 	movb	al,#9
X+ 	j	exception
X+ 
X+ _int10:
X+ 	push	ax
X+ 	movb	al,#10
X+ 	j	exception
X+ 
X+ _int11:
X+ 	push	ax
X+ 	movb	al,#11
X+ 	j	exception
X+ 
X+ _int12:
X+ 	push	ax
X+ 	movb	al,#12
X+ 	j	exception
X+ 
X+ _int13:
X+ 	push	ax
X+ 	movb	al,#13
X+ 	j	exception
X+ 
X+ _int14:
X+ 	push	ax
X+ 	movb	al,#14
X+ 	j	exception
X+ 
X+ _int15:
X+ 	push	ax
X+ 	movb	al,#15
X+ 	j	exception
X+ 
X+ _int16:
X+ 	push	ax
X+ 	movb	al,#16
X+ 	j	exception
X+ 
X+ _trp:
X+ 	push	ax
X+ 	movb	al,#17		| any vector above 17 becomes 17
X+ 
X+ exception:
X+ 	seg	cs
X+ 	movb	ex_number,al	| it's cumbersome to get this into dseg
X+ 	pop	ax
X+ 	call	save
X+ 	seg	cs
X+ 	push	ex_number	| high byte is constant 0
X+ 	call	_exception	| do whatever's necessary (sti only if safe)
X+ 	add	sp,#2
X+ 	cli
X+ 	ret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				save					     *
X+ |*===========================================================================*
X+ save:				| save the machine state in the proc table.
X+ 	cld			| set direction flag to a known value
X+ 	push	ds
X+ 	push	si
X+ 	seg	cs
X+ 	mov	ds,kernel_ds
X+ 	incb	_k_reenter	| from -1 if not reentering
X+ 	jnz	push_current_stack	| stack is already kernel's
X+ 
X+ 	mov	si,_proc_ptr
X+ 	mov	AXREG(si),ax
X+ 	mov	BXREG(si),bx
X+ 	mov	CXREG(si),cx
X+ 	mov	DXREG(si),dx
X+ 	pop	SIREG(si)
X+ 	mov	DIREG(si),di
X+ 	mov	BPREG(si),bp
X+ 	mov	ESREG(si),es
X+ 	pop	DSREG(si)
X+ 	pop	bx		| return adr
X+ 	pop	PCREG(si)
X+ 	pop	CSREG(si)
X+ 	pop	PSWREG(si)
X+ 	mov	SPREG(si),sp
X+ 	mov	SSREG(si),ss
X+ 
X+ 	mov	dx,ds
X+ 	mov	ss,dx
X+ 	mov	sp,#k_stktop
X+ #ifdef SPLIMITS
X+ 	mov	splimit,#k_stack+8
X+ #endif
X+ 	mov	ax,#_restart	| build return address for interrupt handler
X+ 	push	ax
X+ 
X+ stack_switched:
X+ 	mov	es,dx
X+ 	movb	al,#ENABLE	| reenable int controller for everyone (early)
X+ 	out	INT_CTL
X+ 	seg	cs
X+ 	jmpreg	(bx)
X+ 
X+ push_current_stack:
X+ 	push	es
X+ 	push	bp
X+ 	push	di
X+ 	push	dx
X+ 	push	cx
X+ 	push	bx
X+ 	push	ax
X+ 	mov	bp,sp
X+ 	mov	bx,18(bp)	| get the return adr; it becomes junk on stack
X+ 	mov	ax,#restart1
X+ 	push	ax
X+ 	mov	dx,ss
X+ 	mov	ds,dx
X+ 	j	stack_switched
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				s_call					     *
X+ |*===========================================================================*
X+ _s_call:			| System calls are vectored here.
X+ 				| Do save routine inline for speed,
X+ 				| but don't save ax, bx, cx, dx,
X+ 				| since C doesn't require preservation,
X+ 				| and ax returns the result code anyway.
X+ 				| Regs bp, si, di get saved by sys_call as
X+ 				| well, but it is impractical not to preserve
X+ 				| them here, in case context gets switched.
X+ 				| Some special-case code in pick_proc()
X+ 				| could avoid this.
X+ 	cld			| set direction flag to a known value
X+ 	push	ds
X+ 	push	si
X+ 	seg	cs
X+ 	mov	ds,kernel_ds
X+ 	incb	_k_reenter
X+ 	mov	si,_proc_ptr
X+ 	pop	SIREG(si)
X+ 	mov	DIREG(si),di
X+ 	mov	BPREG(si),bp
X+ 	mov	ESREG(si),es
X+ 	pop	DSREG(si)
X+ 	pop	PCREG(si)
X+ 	pop	CSREG(si)
X+ 	pop	PSWREG(si)
X+ 	mov	SPREG(si),sp
X+ 	mov	SSREG(si),ss
X+ 	mov	dx,ds
X+ 	mov	es,dx
X+ 	mov	ss,dx		| interrupt handlers may not make system calls
X+ 	mov	sp,#k_stktop	| so stack is not already switched
X+ #ifdef SPLIMITS
X+ 	mov	splimit,#k_stack+8
X+ #endif
X+ 				| end of inline save
X+ 				| now set up parameters for C routine sys_call
X+ 	push	bx		| pointer to user message
X+ 	push	ax		| src/dest
X+ 	push	cx		| SEND/RECEIVE/BOTH
X+ 	sti			| allow SWITCHER to be interrupted
X+ 	call	_sys_call	| sys_call(function, src_dest, m_ptr)
X+ 				| caller is now explicitly in proc_ptr
X+ 	mov	AXREG(si),ax	| sys_call MUST PRESERVE si
X+ 	cli
X+ 
X+ | Fall into code to restart proc/task running.
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				restart					     *
X+ |*===========================================================================*
X+ _restart:
X+ 
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+ 	cmp	_held_head,#0	| do fast test to usually avoid function call
X+ 	jz	over_call_unhold
X+ 	call	_unhold		| this is rare so overhead is acceptable
X+ over_call_unhold:
X+ 
X+ 	mov	si,_proc_ptr
X+ #ifdef SPLIMITS
X+ 	mov	ax,P_SPLIMIT(si)	| splimit = p_splimit
X+ 	mov	splimit,ax
X+ #endif
X+ 	decb	_k_reenter
X+ 	mov	ax,AXREG(si)	| start restoring registers from proc table
X+ 				| could make AXREG == 0 to use lodw here
X+ 	mov	bx,BXREG(si)
X+ 	mov	cx,CXREG(si)
X+ 	mov	dx,DXREG(si)
X+ 	mov	di,DIREG(si)
X+ 	mov	bp,BPREG(si)
X+ 	mov	es,ESREG(si)
X+ 	mov	ss,SSREG(si)
X+ 	mov	sp,SPREG(si)
X+ 	push	PSWREG(si)	| fake interrupt stack frame
X+ 	push	CSREG(si)
X+ 	push	PCREG(si)
X+ 				| could put si:ds together to use
X+ 				| lds si,SIREG(si)
X+ 	push	DSREG(si)
X+ 	mov	si,SIREG(si)
X+ 	pop	ds
X+ #ifdef DEBUGGER
X+ 	nop			| for db emul. of iret - last pop will skip
X+ #endif
X+ 	iret			| return to user or task
X+ 
X+ restart1:
X+ 	decb	_k_reenter
X+ 	pop	ax
X+ 	pop	bx
X+ 	pop	cx
X+ 	pop	dx
X+ 	pop	di
X+ 	pop	bp
X+ 	pop	es
X+ 	pop	si
X+ 	pop	ds
X+ 	add	sp,#2		| skip return adr
X+ 	iret
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				idle					     *
X+ |*===========================================================================*
X+ _idle_task:			| executed when there is no work 
X+ 	j	_idle_task	| a "hlt" before this fails in protected mode
X+ 
X+ 
X+ |*===========================================================================*
X+ |*				data					     *
X+ |*===========================================================================*
X+ ex_number:			| exception number (stored in code segment)
X+ 	.space	2
X+ 
X+ 	.data
X+ begdata:
X+ _sizes:				| sizes of kernel, mm, fs filled in by build
X+ 	.word	0x526F		| this must be the first data entry (magic #)
X+ 	.zerow	7		| build table uses prev word and this space
X+ k_stack:			| kernel stack
X+ 	.space	K_STACK_BYTES
X+ k_stktop:			| top of kernel stack
X+ 
X+ 	.bss
X+ begbss:
END_OF_FILE
if test 16900 -ne `wc -c <'kerneldif/mpx88.x.cdif'`; then
    echo shar: \"'kerneldif/mpx88.x.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/mpx88.x.cdif'
fi
if test -f 'kerneldif/printer.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/printer.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/printer.c.cdif'\" \(6243 characters\)
sed "s/^X//" >'kerneldif/printer.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/printer.c	Thu Oct  6 21:07:50 1988
X--- kernel/printer.c	Fri Mar 10 00:01:18 1989
X***************
X*** 12,14 ****
X   * -------------------------------------------------------
X!  * | TTY_O_DONE  |minor dev|         |         |         |
X   * |-------------+---------+---------+---------+---------|
X--- 12,14 ----
X   * -------------------------------------------------------
X!  * | TTY_O_DONE  |         |         |         |         |
X   * |-------------+---------+---------+---------+---------|
X***************
X*** 43,45 ****
X  #define PR_MONO_BASE   0x3BC	/* printer port when mono display used */
X- #define LOW_FOUR         0xF	/* mask for low-order 4 bits */
X  #define CANCELED        -999	/* indicates that command has been killed */
X--- 43,44 ----
X***************
X*** 54,61 ****
X  PRIVATE int orig_count;		/* original byte count */
X! PRIVATE int es;			/* (es, offset) point to next character to */
X! PRIVATE int offset;		/* print, i.e., in the user's buffer */
X! PUBLIC int pcount;		/* number of bytes left to print */
X! PUBLIC int pr_busy;		/* TRUE when printing, else FALSE */
X! PUBLIC int cum_count;		/* cumulative # characters printed */
X! PUBLIC int prev_ct;		/* value of cum_count 100 msec ago */
X  
X--- 53,61 ----
X  PRIVATE int orig_count;		/* original byte count */
X! PRIVATE phys_bytes offset;	/* ptr to next char in user's buf to print */
X! PRIVATE int pcount;		/* number of bytes left to print */
X! PRIVATE int pr_busy;		/* TRUE when printing, else FALSE */
X! PRIVATE int cum_count;		/* cumulative # characters printed */
X! PRIVATE int prev_ct;		/* value of cum_count 100 msec ago */
X! PRIVATE int done_status;	/* status of last output completion */
X! PRIVATE message int_mess;	/* interrupt message for 1.3 compatibility */
X  
X***************
X*** 77,80 ****
X  	    case CANCEL   :	do_cancel(&print_mess);	break;
X! 	    case TTY_O_DONE:	do_done(&print_mess);	break;
X!     	    default:					break;
X  	}
X--- 77,82 ----
X  	    case CANCEL   :	do_cancel(&print_mess);	break;
X! 	    case TTY_O_DONE:	do_done();		break;
X! 	    default:		reply(TASK_REPLY, print_mess.m_source,
X! 				      print_mess.PROC_NR, EINVAL);
X! 							break;
X  	}
X***************
X*** 92,96 ****
X  
X!   int i, j, r, value, old_state;
X    struct proc *rp;
X-   phys_bytes phys;
X    extern phys_bytes umap();
X--- 94,97 ----
X  
X!   int i, j, r, value;
X    struct proc *rp;
X    extern phys_bytes umap();
X***************
X*** 105,108 ****
X    rp = proc_addr(m_ptr->PROC_NR);
X!   phys = umap(rp, D, (vir_bytes) m_ptr->ADDRESS, (vir_bytes)m_ptr->COUNT);
X!   if (phys == 0) r = E_BAD_ADDR;
X  
X--- 106,109 ----
X    rp = proc_addr(m_ptr->PROC_NR);
X!   offset = umap(rp, D, (vir_bytes) m_ptr->ADDRESS, (vir_bytes)m_ptr->COUNT);
X!   if (offset == 0) r = E_BAD_ADDR;
X  
X***************
X*** 110,112 ****
X    	/* Save information needed later. */
X! 	old_state = lock();		/* no interrupts now please */
X    	caller = m_ptr->m_source;
X--- 111,113 ----
X    	/* Save information needed later. */
X! 	sim_printer();		/* no printer interrupts now please */
X    	caller = m_ptr->m_source;
X***************
X*** 115,118 ****
X    	orig_count = m_ptr->COUNT;
X-   	es = (int) (phys >> CLICK_SHIFT);
X-   	offset = (int) (phys & LOW_FOUR);
X  
X--- 116,117 ----
X***************
X*** 136,138 ****
X  	}
X!   restore(old_state);
X    }
X--- 135,137 ----
X  	}
X!   cim_printer();
X    }
X***************
X*** 148,151 ****
X   *===========================================================================*/
X! PRIVATE do_done(m_ptr)
X! message *m_ptr;			/* pointer to the newly arrived message */
X  {
X--- 147,149 ----
X   *===========================================================================*/
X! PRIVATE do_done()
X  {
X***************
X*** 155,160 ****
X  
X!   status = (m_ptr->REP_STATUS == OK ? orig_count : EIO);
X    if (proc_nr != CANCELED) {
X    	reply(REVIVE, caller, proc_nr, status);
X!   	if (status == EIO) pr_error(m_ptr->REP_STATUS);
X    }
X--- 153,158 ----
X  
X!   status = (done_status == OK ? orig_count : EIO);
X    if (proc_nr != CANCELED) {
X    	reply(REVIVE, caller, proc_nr, status);
X!   	if (status == EIO) pr_error(done_status);
X    }
X***************
X*** 171,176 ****
X  /* Cancel a print request that has already started.  Usually this means that
X!  * the process doing the printing has been killed by a signal.
X   */
X  
X-   if (pr_busy == FALSE) return;	/* this statement avoids race conditions */
X    pr_busy = FALSE;		/* mark printer as idle */
X--- 169,175 ----
X  /* Cancel a print request that has already started.  Usually this means that
X!  * the process doing the printing has been killed by a signal.  There is no
X!  * need to do anything special about race conditions since resetting the
X!  * flags here is harmless and it is an error to skip the reply.
X   */
X  
X    pr_busy = FALSE;		/* mark printer as idle */
X***************
X*** 246,251 ****
X    int value, ch, i;
X-   char c;
X-   extern char get_byte();
X  
X-   if (pcount != orig_count) port_out(INT_CTL, ENABLE);
X    if (pr_busy == FALSE) return;	/* spurious 8259A interrupt */
X--- 245,247 ----
X***************
X*** 256,259 ****
X  		/* Everything is all right.  Output another character. */
X! 		c = get_byte(es, offset);	/* fetch char from user buf */
X! 		ch = c & BYTE;
X  		port_out(port_base, ch);	/* output character */
X--- 252,254 ----
X  		/* Everything is all right.  Output another character. */
X! 		ch = get_phys_byte(offset);	/* fetch char from user buf */
X  		port_out(port_base, ch);	/* output character */
X***************
X*** 274,276 ****
X    int_mess.m_type = TTY_O_DONE;
X!   int_mess.REP_STATUS = (pcount == 0 ? OK : value);
X    interrupt(PRINTER, &int_mess);
X--- 269,271 ----
X    int_mess.m_type = TTY_O_DONE;
X!   done_status = (pcount == 0 ? OK : value);
X    interrupt(PRINTER, &int_mess);
X***************
X*** 279 ****
X--- 274,287 ----
X  
X+ /*==========================================================================*
X+  *				pr_restart				    *
X+  *==========================================================================*/
X+ PUBLIC pr_restart()
X+ {
X+ /* Check if printer is hung up, and if so, restart it. */
X+ 
X+   if (pr_busy && pcount > 0 && cum_count == prev_ct && !tasim_printer()) {
X+ 	pr_char();
X+ 	cim_printer();
X+   }
X+   prev_ct = cum_count;	/* record # characters printed so far */
X+ }
END_OF_FILE
if test 6243 -ne `wc -c <'kerneldif/printer.c.cdif'`; then
    echo shar: \"'kerneldif/printer.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/printer.c.cdif'
fi
if test -f 'kerneldif/table.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/table.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/table.c.cdif'\" \(1373 characters\)
sed "s/^X//" >'kerneldif/table.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/table.c	Thu Oct  6 21:07:55 1988
X--- kernel/table.c	Thu Mar 23 03:04:00 1989
X***************
X*** 36,37 ****
X--- 36,38 ----
X  
X+ extern int idle_task();
X  extern int sys_task(), clock_task(), mem_task(), floppy_task(),
X***************
X*** 50,51 ****
X--- 51,53 ----
X  #define	TTY_STACK	SMALL_STACK
X+ #define	IDLE_STACK	(3 * 3 * 2)	/* 3 words each for int, temps & db */
X  #define	PRINTER_STACK	SMALL_STACK
X***************
X*** 56,57 ****
X--- 58,60 ----
X  #define	SYS_STACK	SMALL_STACK
X+ #define	HARDWARE_STACK	0		/* dummy task, uses kernel stack */
X  
X***************
X*** 68,69 ****
X--- 71,73 ----
X  #define	TOT_STACK_SPACE		(TTY_STACK + AMOEBA_STACK_SPACE + \
X+ 				 IDLE_STACK + HARDWARE_STACK + \
X  				 PRINTER_STACK + WINCH_STACK + FLOP_STACK + \
X***************
X*** 90,91 ****
X--- 94,96 ----
X  #endif
X+ 	idle_task,		IDLE_STACK,	"IDLE  ",
X  	printer_task,		PRINTER_STACK,	"PRINTR",
X***************
X*** 96,98 ****
X  	sys_task,		SYS_STACK,	"SYS   ",
X! 	0,			0,		"IDLE  ",
X  	0,			0,		"MM    ",
X--- 101,103 ----
X  	sys_task,		SYS_STACK,	"SYS   ",
X! 	0,			HARDWARE_STACK,	"HARDWA",
X  	0,			0,		"MM    ",
X***************
X*** 102,107 ****
X  
X! int t_stack[TOT_STACK_SPACE/sizeof (int)];
X! 
X! int k_stack[K_STACK_BYTES/sizeof (int)];	/* The kernel stack. */
X! 
X  
X--- 107,109 ----
X  
X! PUBLIC char t_stack[TOT_STACK_SPACE + ALIGNMENT - 1];	/* to be aligned */
X  
END_OF_FILE
if test 1373 -ne `wc -c <'kerneldif/table.c.cdif'`; then
    echo shar: \"'kerneldif/table.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/table.c.cdif'
fi
echo shar: End of archive 6 \(of 10\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!agate!helios.ee.lbl.gov!ncis.tis.llnl.gov!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 7 - By Bruce Evans
Message-ID: <5269@ditmela.oz>
Date: 18 May 89 01:26:01 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1166


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 10)."
# Contents:  kerneldif/proc.c.cdif kerneldif/proc.h.cdif
#   kerneldif/protect.h.cdif kerneldif/type.h.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/proc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/proc.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/proc.c.cdif'\" \(26431 characters\)
sed "s/^X//" >'kerneldif/proc.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/proc.c	Fri Oct  7 21:02:44 1988
X--- kernel/proc.c	Thu Mar 23 01:05:42 1989
X***************
X*** 6,14 ****
X   *
X!  * It also has five minor entry points:
X   *
X!  *   ready:	put a process on one of the ready queues so it can be run
X!  *   unready:	remove a process from the ready queues
X!  *   sched:	a process has run too long; schedule another one
X!  *   mini_send:	send a message (used by interrupt signals, etc.)
X!  *   pick_proc:	pick a process to run (used by system initialization)
X   */
X--- 6,16 ----
X   *
X!  * It also has several minor entry points:
X   *
X!  *   lockready:	put a process on one of the ready queues so it can be run
X!  *   lockunready:	remove a process from the ready queues
X!  *   locksched:	a process has run too long; schedule another one
X!  *   lockmini_send:	send a message (used by interrupt signals, etc.)
X!  *   lockpick_proc:	pick a process to run (used by system initialization)
X!  *   proc_init:	initialize the process table
X!  *   unhold:	repeat all held-up interrupts
X   */
X***************
X*** 25,26 ****
X--- 27,30 ----
X  
X+ PRIVATE unsigned char switching;	/* nonzero to inhibit interrupt() */
X+ 
X  /*===========================================================================*
X***************
X*** 28,32 ****
X   *===========================================================================*/
X! PUBLIC interrupt(task, m_ptr)
X  int task;			/* number of task to be started */
X- message *m_ptr;			/* interrupt message to send to the task */
X  {
X--- 32,35 ----
X   *===========================================================================*/
X! PUBLIC interrupt(task)
X  int task;			/* number of task to be started */
X  {
X***************
X*** 34,81 ****
X  
X!   int i, n, old_map, this_bit;
X  
X! #ifdef i8088
X!   /* Re-enable the 8259A interrupt controller. */
X!   if (ps && task==FLOPPY)port_out(0x3C, ENABLE);/* Nonspecific End-Of-Int ps */
X  
X!   port_out(INT_CTL, ENABLE);	/* this re-enables the 8259A controller chip */
X!   if (pc_at && task == WINCHESTER)
X! 	  /* this re-enables the second controller chip */
X! 	  port_out(INT2_CTL, ENABLE);
X! #endif
X! 
X!   /* Try to send the interrupt message to the indicated task. */
X!   this_bit = 1 << (-task);
X!   if (mini_send(HARDWARE, task, m_ptr) != OK) {
X! 	/* The message could not be sent to the task; it was not waiting. */
X! 	old_map = busy_map;	/* save original map of busy tasks */
X! 	if (task == CLOCK) {
X! 		lost_ticks++;
X! 	} else {
X! 		busy_map |= this_bit;		/* mark task as busy */
X! 		task_mess[-task] = m_ptr;	/* record message pointer */
X  	}
X!   } else {
X! 	/* Hardware interrupt was successfully sent as a message. */
X! 	busy_map &= ~this_bit;	/* turn off the bit in case it was on */
X! 	old_map = busy_map;
X    }
X  
X!   /* See if any tasks that were previously busy are now listening for msgs. */
X!   if (old_map != 0) {
X! 	for (i = 2; i <= NR_TASKS; i++) {
X! 		/* Check each task looking for one with a pending interrupt. */
X! 		if ( (old_map>>i) & 1) {
X! 			/* Task 'i' has a pending interrupt. */
X! 			n = mini_send(HARDWARE, -i, task_mess[i]);
X! 			if (n == OK) busy_map &= ~(1 << i);
X! 		}
X! 	}
X    }
X  
X!   /* If a task has just been readied and a user is running, run the task. */
X!   if (rdy_head[TASK_Q] != NIL_PROC && (cur_proc >= 0 || cur_proc == IDLE))
X! 	pick_proc();
X! }
X  
X  
X--- 37,105 ----
X  
X!   register struct proc *rp;	/* pointer to task's proc entry */
X  
X!   rp = proc_addr(task);
X  
X!   /* If this call would compete with other process-switching functions, put
X!    * it on the 'held' queue to be flushed at the next non-competing restart().
X!    * The competing conditions are:
X!    * (1) k_reenter == (typeof k_reenter) -1:
X!    *     Call from the task level, typically from an output interrupt
X!    *     routine.  An interrupt handler might reenter interrupt().  Rare,
X!    *     so not worth special treatment.
X!    * (2) k_reenter > 0:
X!    *     Call from a nested interrupt handler.  A previous interrupt handler
X!    *     might be inside interrupt() or sys_call().
X!    * (3) switching != 0:
X!    *     Some process-switching function other than interrupt() is being
X!    *     called from the task level, typically sched() from CLOCK.  An
X!    *     interrupt handler might call interrupt and pass the k_reenter test.
X!    */
X!   if (k_reenter != 0 || switching) {
X! 	lock();
X! 	if (!rp->p_int_held) {
X! 		rp->p_int_held = TRUE;
X! 		if (held_head != NIL_PROC)
X! 			held_tail->p_nextheld = rp;
X! 		else
X! 			held_head = rp;
X! 		held_tail = rp;
X! 		rp->p_nextheld = NIL_PROC;
X  	}
X! 	unlock();
X! 	return;
X    }
X  
X!   /* If task is not waiting for an interrupt, record the blockage. */
X!   if ( (rp->p_flags & (RECEIVING | SENDING)) != RECEIVING ||
X!       !isrxhardware(rp->p_getfrom)) {
X! 	rp->p_int_blocked = TRUE;
X! 	return;
X    }
X  
X!   /* Destination is waiting for an interrupt.
X!    * Send it a message with source HARDWARE and type HARD_INT.
X!    * No more information can be reliably provided since interrupt messages
X!    * are not queued.
X!    */
X!   rp->p_messbuf->m_source = HARDWARE;
X!   rp->p_messbuf->m_type = HARD_INT;
X!   rp->p_flags &= ~RECEIVING;
X!   rp->p_int_blocked = FALSE;
X  
X+    /* Duplicate relevant part of ready() in-line. */
X+   if (rdy_head[TASK_Q] != NIL_PROC)
X+ 	rdy_tail[TASK_Q]->p_nextready = rp;
X+   else
X+ 	rdy_head[TASK_Q] = rp;
X+   rdy_tail[TASK_Q] = rp;
X+   rp->p_nextready = NIL_PROC;
X+   
X+   /* If a non-task is running and a task is ready, run the task.
X+    * Duplicate relevant part of pick_proc() in-line.  One assignment!
X+    * Bill_ptr stays unchanged.
X+    */
X+   if (!istaskp(proc_ptr) && (rp = rdy_head[TASK_Q]) != NIL_PROC)
X+ 	proc_ptr = rp;
X+ }
X+ 
X  
X***************
X*** 84,88 ****
X   *===========================================================================*/
X! PUBLIC sys_call(function, caller, src_dest, m_ptr)
X  int function;			/* SEND, RECEIVE, or BOTH */
X- int caller;			/* who is making this call */
X  int src_dest;			/* source to receive from or dest to send to */
X--- 108,111 ----
X   *===========================================================================*/
X! PUBLIC int sys_call(function, src_dest, m_ptr)
X  int function;			/* SEND, RECEIVE, or BOTH */
X  int src_dest;			/* source to receive from or dest to send to */
X***************
X*** 92,95 ****
X   * messages.  These are done by trapping to the kernel with an INT instruction.
X!  * The trap is caught and sys_call() is called to send or receive a message (or
X!  * both).
X   */
X--- 115,118 ----
X   * messages.  These are done by trapping to the kernel with an INT instruction.
X!  * The trap is caught and sys_call() is called to send or receive a message
X!  * (or both). The caller is always given by proc_ptr.
X   */
X***************
X*** 100,110 ****
X    /* Check for bad system call parameters. */
X!   rp = proc_addr(caller);
X!   if (src_dest < -NR_TASKS || (src_dest >= NR_PROCS && src_dest != ANY) ) {
X! 	rp->p_reg[RET_REG] = E_BAD_SRC;
X! 	return;
X!   }
X!   if (function != BOTH && caller >= LOW_USER) {
X! 	rp->p_reg[RET_REG] = E_NO_PERM;	/* users only do BOTH */
X! 	return;
X!   }
X  
X--- 123,129 ----
X    /* Check for bad system call parameters. */
X!   if (!isoksrc_dest(src_dest))
X! 	return(E_BAD_SRC);
X!   rp = proc_ptr;
X!   if (function != BOTH && isuserp(rp))
X! 	return(E_NO_PERM);	/* users only do BOTH */
X  
X***************
X*** 112,122 ****
X    if (function & SEND) {
X! 	n = mini_send(caller, src_dest, m_ptr);	/* func = SEND or BOTH */
X! 	if (function == SEND || n != OK) rp->p_reg[RET_REG] = n;
X! 	if (n != OK) return;	/* SEND failed */
X    }
X  
X!   if (function & RECEIVE) {
X! 	n = mini_rec(caller, src_dest, m_ptr);      /* func = RECEIVE or BOTH*/
X! 	rp->p_reg[RET_REG] = n;
X!   }
X  }
X--- 131,142 ----
X    if (function & SEND) {
X! 	/* Function = SEND or BOTH. */
X! 	n = mini_send(rp, src_dest, m_ptr);
X! 	if (function == SEND || n != OK)
X! 		return(n);	/* done, or SEND failed */
X    }
X  
X!   /* Function = RECEIVE or BOTH.
X!    * We have checked user calls are BOTH, and trust 'function' otherwise.
X!    */
X!   return(mini_rec(rp, src_dest, m_ptr));
X  }
X***************
X*** 126,146 ****
X   *===========================================================================*/
X! PUBLIC int mini_send(caller, dest, m_ptr)
X! int caller;			/* who is trying to send a message? */
X  int dest;			/* to whom is message being sent? */
X  message *m_ptr;			/* pointer to message buffer */
X  {
X! /* Send a message from 'caller' to 'dest'.  If 'dest' is blocked waiting for
X!  * this message, copy the message to it and unblock 'dest'.  If 'dest' is not
X!  * waiting at all, or is waiting for another source, queue 'caller'.
X   */
X  
X!   register struct proc *caller_ptr, *dest_ptr, *next_ptr;
X    vir_bytes vb;			/* message buffer pointer as vir_bytes */
X    vir_clicks vlo, vhi;		/* virtual clicks containing message to send */
X-   vir_clicks len;		/* length of data segment in clicks */
X  
X    /* User processes are only allowed to send to FS and MM.  Check for this. */
X!   if (caller >= LOW_USER && (dest != FS_PROC_NR && dest != MM_PROC_NR))
X  	return(E_BAD_DEST);
X-   caller_ptr = proc_addr(caller);	/* pointer to source's proc entry */
X    dest_ptr = proc_addr(dest);	/* pointer to destination's proc entry */
X--- 146,165 ----
X   *===========================================================================*/
X! PRIVATE int mini_send(caller_ptr, dest, m_ptr)
X! register struct proc *caller_ptr;	/* who is trying to send a message? */
X  int dest;			/* to whom is message being sent? */
X  message *m_ptr;			/* pointer to message buffer */
X+ 
X  {
X! /* Send a message from 'caller_ptr' to 'dest'. If 'dest' is blocked waiting
X!  * for this message, copy the message to it and unblock 'dest'. If 'dest' is
X!  * not waiting at all, or is waiting for another source, queue 'caller_ptr'.
X   */
X  
X!   register struct proc *dest_ptr, *next_ptr;
X    vir_bytes vb;			/* message buffer pointer as vir_bytes */
X    vir_clicks vlo, vhi;		/* virtual clicks containing message to send */
X  
X    /* User processes are only allowed to send to FS and MM.  Check for this. */
X!   if (isuserp(caller_ptr) && !isservn(dest))
X  	return(E_BAD_DEST);
X    dest_ptr = proc_addr(dest);	/* pointer to destination's proc entry */
X***************
X*** 149,151 ****
X    /* Check for messages wrapping around top of memory or outside data seg. */
X-   len = caller_ptr->p_map[D].mem_len;
X    vb = (vir_bytes) m_ptr;
X--- 168,169 ----
X***************
X*** 153,160 ****
X    vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;	/* vir click for top of msg */
X!   if (vhi < vlo || vhi - caller_ptr->p_map[D].mem_vir >=len)return(E_BAD_ADDR);
X  
X!   /* Check for deadlock by 'caller' and 'dest' sending to each other. */
X    if (dest_ptr->p_flags & SENDING) {
X  	next_ptr = caller_ptr->p_callerq;
X! 	while (next_ptr) {
X  		if (next_ptr == dest_ptr)
X--- 171,180 ----
X    vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;	/* vir click for top of msg */
X!   if (vhi < vlo ||
X!       vhi - caller_ptr->p_map[D].mem_vir >= caller_ptr->p_map[D].mem_len)
X! 	return(E_BAD_ADDR);
X  
X!   /* Check for deadlock by 'caller_ptr' and 'dest' sending to each other. */
X    if (dest_ptr->p_flags & SENDING) {
X  	next_ptr = caller_ptr->p_callerq;
X! 	while (next_ptr != NIL_PROC) {
X  		if (next_ptr == dest_ptr)
X***************
X*** 166,171 ****
X    /* Check to see if 'dest' is blocked waiting for this message. */
X!   if ( (dest_ptr->p_flags & RECEIVING) && (dest_ptr->p_flags & SENDING) == 0 &&
X! 		(dest_ptr->p_getfrom == ANY || dest_ptr->p_getfrom == caller)){
X  	/* Destination is indeed waiting for this message. */
X! 	cp_mess(caller, caller_ptr->p_map[D].mem_phys, m_ptr, 
X  			   dest_ptr->p_map[D].mem_phys, dest_ptr->p_messbuf);
X--- 186,192 ----
X    /* Check to see if 'dest' is blocked waiting for this message. */
X!   if ( (dest_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
X!        (dest_ptr->p_getfrom == ANY ||
X!         dest_ptr->p_getfrom == proc_number(caller_ptr))) {
X  	/* Destination is indeed waiting for this message. */
X! 	cp_mess(proc_number(caller_ptr), caller_ptr->p_map[D].mem_phys, m_ptr,
X  			   dest_ptr->p_map[D].mem_phys, dest_ptr->p_messbuf);
X***************
X*** 175,177 ****
X  	/* Destination is not waiting.  Block and queue caller. */
X- 	if (caller == HARDWARE) return(E_OVERRUN);
X  	caller_ptr->p_messbuf = m_ptr;
X--- 196,197 ----
X***************
X*** 181,185 ****
X  	/* Process is now blocked.  Put in on the destination's queue. */
X! 	if ( (next_ptr = dest_ptr->p_callerq) == NIL_PROC) {
X  		dest_ptr->p_callerq = caller_ptr;
X! 	} else {
X  		while (next_ptr->p_sendlink != NIL_PROC)
X--- 201,205 ----
X  	/* Process is now blocked.  Put in on the destination's queue. */
X! 	if ( (next_ptr = dest_ptr->p_callerq) == NIL_PROC)
X  		dest_ptr->p_callerq = caller_ptr;
X! 	else {
X  		while (next_ptr->p_sendlink != NIL_PROC)
X***************
X*** 197,200 ****
X   *===========================================================================*/
X! PRIVATE int mini_rec(caller, src, m_ptr)
X! int caller;			/* process trying to get message */
X  int src;			/* which message source is wanted (or ANY) */
X--- 217,220 ----
X   *===========================================================================*/
X! PRIVATE int mini_rec(caller_ptr, src, m_ptr)
X! register struct proc *caller_ptr;	/* process trying to get message */
X  int src;			/* which message source is wanted (or ANY) */
X***************
X*** 209,226 ****
X  
X!   register struct proc *caller_ptr, *sender_ptr, *previous_ptr;
X!   int sender;
X  
X-   caller_ptr = proc_addr(caller);	/* pointer to caller's proc struct */
X- 
X    /* Check to see if a message from desired source is already available. */
X!   sender_ptr = caller_ptr->p_callerq;
X!   if ((caller_ptr->p_flags & SENDING) == 0) {
X!      while (sender_ptr != NIL_PROC) {
X! 	sender = sender_ptr - proc - NR_TASKS;
X! 	if (src == ANY || src == sender) {
X  		/* An acceptable message has been found. */
X! 		cp_mess(sender, sender_ptr->p_map[D].mem_phys, 
X! 		  sender_ptr->p_messbuf, caller_ptr->p_map[D].mem_phys, m_ptr);
X! 		sender_ptr->p_flags &= ~SENDING;	/* deblock sender */
X! 		if (sender_ptr->p_flags == 0) ready(sender_ptr);
X  		if (sender_ptr == caller_ptr->p_callerq)
X--- 229,244 ----
X  
X!   register struct proc *sender_ptr;
X!   register struct proc *previous_ptr;
X!   int dest;
X  
X    /* Check to see if a message from desired source is already available. */
X!   if (!(caller_ptr->p_flags & SENDING)) {
X! 	/* Check caller queue. */
X!     for (sender_ptr = caller_ptr->p_callerq; sender_ptr != NIL_PROC;
X! 	  previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_sendlink) {
X! 	if (src == ANY || src == proc_number(sender_ptr)) {
X  		/* An acceptable message has been found. */
X! 		cp_mess(proc_number(sender_ptr),
X! 			sender_ptr->p_map[D].mem_phys, sender_ptr->p_messbuf,
X! 			caller_ptr->p_map[D].mem_phys, m_ptr);
X  		if (sender_ptr == caller_ptr->p_callerq)
X***************
X*** 229,237 ****
X  			previous_ptr->p_sendlink = sender_ptr->p_sendlink;
X  		return(OK);
X  	}
X! 	previous_ptr = sender_ptr;
X! 	sender_ptr = sender_ptr->p_sendlink;
X!      }
X!   }
X  
X    /* No suitable message is available.  Block the process trying to receive. */
X--- 247,263 ----
X  			previous_ptr->p_sendlink = sender_ptr->p_sendlink;
X+ 		if ((sender_ptr->p_flags &= ~SENDING) == 0)
X+ 			ready(sender_ptr);	/* deblock sender */
X  		return(OK);
X  	}
X!     }
X  
X+     /* Check for blocked interrupt. */
X+     if (caller_ptr->p_int_blocked && isrxhardware(src)) {
X+ 	m_ptr->m_source = HARDWARE;
X+ 	m_ptr->m_type = HARD_INT;
X+ 	caller_ptr->p_int_blocked = FALSE;
X+ 	return(OK);
X+     }
X+   }
X+ 
X    /* No suitable message is available.  Block the process trying to receive. */
X***************
X*** 245,250 ****
X     */
X!   if (sig_procs > 0 && caller == MM_PROC_NR && src == ANY) {
X  	inform();
X- 	pick_proc();
X-   }
X    return(OK);
X--- 271,274 ----
X     */
X!   if (sig_procs > 0 && proc_number(caller_ptr) == MM_PROC_NR && src == ANY)
X  	inform();
X    return(OK);
X***************
X*** 256,258 ****
X   *===========================================================================*/
X! PUBLIC pick_proc()
X  {
X--- 280,282 ----
X   *===========================================================================*/
X! PRIVATE pick_proc()
X  {
X***************
X*** 260,288 ****
X  
X!   register int q;		/* which queue to use */
X  
X!   if (rdy_head[TASK_Q] != NIL_PROC) q = TASK_Q;
X!   else if (rdy_head[SERVER_Q] != NIL_PROC) q = SERVER_Q;
X!   else q = USER_Q;
X  
X!   /* Set 'cur_proc' and 'proc_ptr'. If system is idle, set 'cur_proc' to a
X!    * special value (IDLE), and set 'proc_ptr' to point to an unused proc table
X!    * slot, namely, that of task -1 (HARDWARE), so save() will have somewhere to
X!    * deposit the registers when an interrupt occurs on an idle machine.
X!    * Record previous process so that when clock tick happens, the clock task
X!    * can find out who was running just before it began to run. (While the clock
X!    * task is running, 'cur_proc' = CLOCKTASK.) In addition, set 'bill_ptr'
X!    * to always point to the process to be billed for CPU time.
X     */
X!   prev_proc = cur_proc;
X!   if (rdy_head[q] != NIL_PROC) {
X! 	/* Someone is runnable. */
X! 	cur_proc = rdy_head[q] - proc - NR_TASKS;
X! 	proc_ptr = rdy_head[q];
X! 	if (cur_proc >= LOW_USER) bill_ptr = proc_ptr;
X!   } else {
X! 	/* No one is runnable. */
X! 	cur_proc = IDLE;
X! 	proc_ptr = proc_addr(HARDWARE);
X! 	bill_ptr = proc_ptr;
X!   }
X  }
X--- 284,305 ----
X  
X!   register struct proc *rp;	/* which queue to use */
X  
X!   if ( (rp = rdy_head[TASK_Q]) == NIL_PROC &&
X!        (rp = rdy_head[SERVER_Q]) == NIL_PROC &&
X!        (rp = rdy_head[USER_Q]) == NIL_PROC) {
X! 	/* Run the idle task. */
X! 	bill_ptr = proc_ptr = cproc_addr(IDLE);
X! 	return;
X!   }
X  
X!   /* The new process is selected just by pointing proc_ptr at it.
X!    * When a clock tick occurs while a non-user is running, the clock task has
X!    * to decide which process to bill for system time.
X!    * It uses the last user (or idle) process, which is recorded in 'bill_ptr'.
X!    * This is slightly inaccurate because the last user gets billed for all
X!    * interrupt activity.
X     */
X!   proc_ptr = rp;
X!   if (isuserp(rp))
X! 	bill_ptr = rp;
X  }
X***************
X*** 292,294 ****
X   *===========================================================================*/
X! PUBLIC ready(rp)
X  register struct proc *rp;	/* this process is now runnable */
X--- 309,311 ----
X   *===========================================================================*/
X! PRIVATE ready(rp)
X  register struct proc *rp;	/* this process is now runnable */
X***************
X*** 302,318 ****
X  
X!   register int q;		/* TASK_Q, SERVER_Q, or USER_Q */
X!   int r, old_state;
X! 
X!   old_state = lock();		/* disable interrupts */
X!   r = (rp - proc) - NR_TASKS;	/* task or proc number */
X!   q = (r < 0 ? TASK_Q : r < LOW_USER ? SERVER_Q : USER_Q);
X! 
X!   /* See if the relevant queue is empty. */
X!   if (rdy_head[q] == NIL_PROC)
X! 	rdy_head[q] = rp;	/* add to empty queue */
X    else
X! 	rdy_tail[q]->p_nextready = rp;	/* add to tail of nonempty queue */
X!   rdy_tail[q] = rp;		/* new entry has no successor */
X    rp->p_nextready = NIL_PROC;
X-   restore(old_state);		/* restore interrupts to previous state */
X  }
X--- 319,345 ----
X  
X!   if (istaskp(rp)) {
X! 	if (rdy_head[TASK_Q] != NIL_PROC)
X! 		/* Add to tail of nonempty queue. */
X! 		rdy_tail[TASK_Q]->p_nextready = rp;
X! 	else
X! 		rdy_head[TASK_Q] = rp;	/* add to empty queue */
X! 	rdy_tail[TASK_Q] = rp;
X! 	rp->p_nextready = NIL_PROC;	/* new entry has no successor */
X! 	return;
X!   }
X!   if (!isuserp(rp)) {		/* others are similar */
X! 	if (rdy_head[SERVER_Q] != NIL_PROC)
X! 		rdy_tail[SERVER_Q]->p_nextready = rp;
X! 	else
X! 		rdy_head[SERVER_Q] = rp;
X! 	rdy_tail[SERVER_Q] = rp;
X! 	rp->p_nextready = NIL_PROC;
X! 	return;
X!   }
X!   if (rdy_head[USER_Q] != NIL_PROC)
X! 	rdy_tail[USER_Q]->p_nextready = rp;
X    else
X! 	rdy_head[USER_Q] = rp;
X!   rdy_tail[USER_Q] = rp;
X    rp->p_nextready = NIL_PROC;
X  }
X***************
X*** 323,325 ****
X   *===========================================================================*/
X! PUBLIC unready(rp)
X  register struct proc *rp;	/* this process is no longer runnable */
X--- 350,352 ----
X   *===========================================================================*/
X! PRIVATE unready(rp)
X  register struct proc *rp;	/* this process is no longer runnable */
X***************
X*** 329,359 ****
X    register struct proc *xp;
X!   int r, q, old_state;
X  
X!   old_state = lock();			/* disable interrupts */
X!   r = rp - proc - NR_TASKS;
X!   q = (r < 0 ? TASK_Q : r < LOW_USER ? SERVER_Q : USER_Q);
X!   if ( (xp = rdy_head[q]) == NIL_PROC) {
X! 	restore(old_state);
X! 	return;
X    }
X!   if (xp == rp) {
X! 	/* Remove head of queue */
X! 	rdy_head[q] = xp->p_nextready;
X! 	if (rp == proc_ptr) pick_proc();
X    } else {
X! 	/* Search body of queue.  A process can be made unready even if it is
X! 	 * not running by being sent a signal that kills it.
X! 	 */
X! 	while (xp->p_nextready != rp)
X! 		if ( (xp = xp->p_nextready) == NIL_PROC) {
X! 			restore(old_state);
X! 			return;
X! 		}
X! 	xp->p_nextready = xp->p_nextready->p_nextready;
X! 	while (xp->p_nextready != NIL_PROC) xp = xp->p_nextready;
X! 	rdy_tail[q] = xp;
X    }
X-   restore(old_state);			/* restore interrupts to prev state */
X- }
X  
X  
X--- 356,407 ----
X    register struct proc *xp;
X!   register struct proc **qhead;  /* TASK_Q, SERVER_Q, or USER_Q rdy_head */
X!   register struct proc **qtail;
X  
X!   if (istaskp(rp)) {
X! 	if ( (xp = rdy_head[TASK_Q]) == NIL_PROC)
X! 		return;
X! 	if (xp == rp) {
X! 		/* Remove head of queue */
X! 		rdy_head[TASK_Q] = xp->p_nextready;
X! 		if (rp == proc_ptr)
X! 			pick_proc();
X! 		return;
X! 	}
X! 	qhead = &rdy_head[TASK_Q];
X! 	qtail = &rdy_tail[TASK_Q];
X    }
X!   else if (!isuserp(rp)) {
X! 	if ( (xp = rdy_head[SERVER_Q]) == NIL_PROC)
X! 		return;
X! 	if (xp == rp) {
X! 		rdy_head[SERVER_Q] = xp->p_nextready;
X! 		pick_proc();
X! 		return;
X! 	}
X! 	qhead = &rdy_head[SERVER_Q];
X! 	qtail = &rdy_tail[SERVER_Q];
X    } else {
X! 	if ( (xp = rdy_head[USER_Q]) == NIL_PROC)
X! 		return;
X! 	if (xp == rp) {
X! 		rdy_head[USER_Q] = xp->p_nextready;
X! 		pick_proc();
X! 		return;
X! 	}
X! 	qhead = &rdy_head[USER_Q];
X! 	qtail = &rdy_tail[USER_Q];
X    }
X  
X+   /* Search body of queue.  A process can be made unready even if it is
X+    * not running by being sent a signal that kills it.
X+    */
X+   while (xp->p_nextready != rp)
X+ 	if ( (xp = xp->p_nextready) == NIL_PROC)
X+ 		return;
X+   xp->p_nextready = xp->p_nextready->p_nextready;
X+   while (xp->p_nextready != NIL_PROC)
X+ 	xp = xp->p_nextready;
X+   *qtail = xp;
X+ }
X+ 
X  
X***************
X*** 362,364 ****
X   *===========================================================================*/
X! PUBLIC sched()
X  {
X--- 410,412 ----
X   *===========================================================================*/
X! PRIVATE sched()
X  {
X***************
X*** 369,378 ****
X  
X!   int old_state;
X  
X-   old_state = lock();			/* disable interrupts */
X-   if (rdy_head[USER_Q] == NIL_PROC) {
X- 	restore(old_state);		/* restore interrupts to prev state */
X- 	return;
X-   }
X- 
X    /* One or more user processes queued. */
X--- 417,421 ----
X  
X!   if (rdy_head[USER_Q] == NIL_PROC)
X!  	return;
X  
X    /* One or more user processes queued. */
X***************
X*** 383,385 ****
X    pick_proc();
X!   restore(old_state);			/* restore interrupts to prev state */
X  }
X--- 426,538 ----
X    pick_proc();
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				proc_init				    *
X!  *==========================================================================*/
X! PUBLIC proc_init()
X! {
X! /* Clear process table.
X!  * Set up mappings for proc_addr() and proc_number() macros.
X!  */
X! 
X!   register struct proc *rp;
X!   int proc_nr;
X! 
X!   for (rp = BEG_PROC_ADDR, proc_nr = -NR_TASKS; rp < END_PROC_ADDR;
X!        ++rp, ++proc_nr) {
X! 	rp->p_flags = P_SLOT_FREE;
X! 	rp->p_nr = proc_nr;	/* proc number from ptr */
X! 	(pproc_addr + NR_TASKS)[proc_nr] = rp;	/* proc ptr from number */
X!   }
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				lockmini_send				    *
X!  *==========================================================================*/
X! PUBLIC int lockmini_send(caller_ptr, dest, m_ptr)
X! struct proc *caller_ptr;
X! int dest;
X! message *m_ptr;
X! {
X!   int mini_result;
X! 
X!   switching = TRUE;
X!   mini_result = mini_send(caller_ptr, dest, m_ptr);
X!   switching = FALSE;
X!   return(mini_result);
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				lockpick_proc				    *
X!  *==========================================================================*/
X! PUBLIC lockpick_proc()
X! {
X!   switching = TRUE;
X!   pick_proc();
X!   switching = FALSE;
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				lockready				    *
X!  *==========================================================================*/
X! PUBLIC lockready(rp)
X! struct proc *rp;
X! {
X!   switching = TRUE;
X!   ready(rp);
X!   switching = FALSE;
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				locksched				    *
X!  *==========================================================================*/
X! PUBLIC locksched()
X! {
X!   switching = TRUE;
X!   sched();
X!   switching = FALSE;
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				lockunready				    *
X!  *==========================================================================*/
X! PUBLIC lockunready(rp)
X! struct proc *rp;
X! {
X!   switching = TRUE;
X!   unready(rp);
X!   switching = FALSE;
X! }
X! 
X! 
X! /*==========================================================================*
X!  *				unhold					    *
X!  *==========================================================================*/
X! PUBLIC unhold()
X! {
X! /* Flush any held-up interrupts.  k_reenter must be 0.  held_head must not
X!  * be NIL_PROC.  Interrupts must be disabled.  They will be enabled but will
X!  * be disabled when this returns.
X!  */
X! 
X!   register struct proc *rp;	/* current head of held queue */
X! 
X!   if (switching)
X! 	return;
X!   rp = held_head;
X!   do {
X! 	if ( (held_head = rp->p_nextheld) == NIL_PROC)
X! 		held_tail = NIL_PROC;
X! 	rp->p_int_held = FALSE;
X! 	unlock();		/* reduce latency; held queue may change! */
X! 	interrupt(proc_number(rp));
X! 	lock();			/* protect the held queue */
X!   }
X!   while ( (rp = held_head) != NIL_PROC);
X  }
END_OF_FILE
if test 26431 -ne `wc -c <'kerneldif/proc.c.cdif'`; then
    echo shar: \"'kerneldif/proc.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/proc.c.cdif'
fi
if test -f 'kerneldif/proc.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/proc.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/proc.h.cdif'\" \(4435 characters\)
sed "s/^X//" >'kerneldif/proc.h.cdif' <<'END_OF_FILE'
X*** kernel-1.3/proc.h	Wed Aug  3 21:18:39 1988
X--- kernel/proc.h	Thu Mar 23 03:04:33 1989
X***************
X*** 1,6 ****
X! /* Here is the declaration of the process table.  Three assembly code routines
X!  * reference fields in it.  They are restart(), save(), and csv().  When 
X!  * changing 'proc', be sure to change the field offsets built into the code.
X!  * It contains the process' registers, memory map, accounting, and message
X!  * send/receive information.
X   */
X--- 1,6 ----
X! /* Here is the declaration of the process table.  It contains the process'
X!  * registers, memory map, accounting, and message send/receive information.
X!  * Many assembly code routines reference fields in it.  The offsets to these
X!  * fields are defined in the assembler include file sconst.h.  When changing
X!  * 'proc', be sure to change sconst.h to match.
X   */
X***************
X*** 8,15 ****
X  EXTERN struct proc {
X!   int p_reg[NR_REGS];		/* process' registers */
X!   int *p_sp;			/* stack pointer */
X!   struct pc_psw p_pcpsw;	/* pc and psw as pushed by interrupt */
X    int p_flags;			/* P_SLOT_FREE, SENDING, RECEIVING, etc. */
X    struct mem_map p_map[NR_SEGS];/* memory map */
X-   int *p_splimit;		/* lowest legal stack value */
X    int p_pid;			/* process id passed in from MM */
X--- 8,26 ----
X  EXTERN struct proc {
X!   union stackframe_u p_reg;	/* process' registers saved in stack frame */
X!   int p_nr;			/* number of this process (for fast access) */
X! 
X! #ifdef i80286
X!   u16_t p_ldt_sel;		/* selector in gdt giving ldt base and limit*/
X!   struct segdesc_s p_ldt[2];	/* local descriptor table cs:ds */
X! 				/* 2 is LDT_SIZE - avoid include protect.h */
X! #endif
X! 
X!   u16_t p_splimit;		/* lowest legal stack value */
X! 
X!   int p_int_blocked;		/* nonzero if int msg blocked by busy task */
X!   int p_int_held;		/* nonzero if int msg held by busy syscall */
X!   struct proc *p_nextheld;	/* next in chain of held-up int processes */
X! 
X    int p_flags;			/* P_SLOT_FREE, SENDING, RECEIVING, etc. */
X    struct mem_map p_map[NR_SEGS];/* memory map */
X    int p_pid;			/* process id passed in from MM */
X***************
X*** 29,31 ****
X    int p_pending;		/* bit map for pending signals 1-16 */
X! } proc[NR_TASKS+NR_PROCS];
X  
X--- 40,43 ----
X    int p_pending;		/* bit map for pending signals 1-16 */
X!   unsigned p_pendcount;		/* count of pending and unfinished signals */
X! };
X  
X***************
X*** 36,42 ****
X  #define RECEIVING        010	/* set when process blocked trying to recv */
X! #define PENDING          020	/* set when process has signals pending */
X  
X! #define proc_addr(n) &proc[NR_TASKS + n]
X! #define NIL_PROC (struct proc *) 0
X  
X  EXTERN struct proc *proc_ptr;	/* &proc[cur_proc] */
X--- 48,76 ----
X  #define RECEIVING        010	/* set when process blocked trying to recv */
X! #define PENDING          020	/* set when inform() of signal pending */
X! #define SIG_PENDING      040	/* keeps to-be-signalled proc from running */
X  
X! /* Magic process table addresses. */
X! #define BEG_PROC_ADDR (&proc[0])
X! #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
X! #define END_TASK_ADDR (&proc[NR_TASKS])
X! #define BEG_SERV_ADDR (&proc[NR_TASKS])
X! #define BEG_USER_ADDR (&proc[NR_TASKS + LOW_USER])
X  
X+ #define NIL_PROC (struct proc *) 0
X+ #define isidlehardware( n ) ((n) == IDLE || (n) == HARDWARE)
X+ #define isokprocn( n ) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
X+ #define isoksrc_dest( n ) (isokprocn( n ) || (n) == ANY)
X+ #define isoksusern( n ) ((unsigned) (n) < NR_PROCS)
X+ #define isokusern( n ) ((unsigned) ((n) - LOW_USER) < NR_PROCS - LOW_USER)
X+ #define isrxhardware( n ) ((n) == ANY || (n) == HARDWARE)
X+ #define isservn( n ) ((unsigned) (n) < LOW_USER)
X+ #define istaskp( p ) ((p) < END_TASK_ADDR && (p) != cproc_addr( IDLE ))
X+ #define isuserp( p ) ((p) >= BEG_USER_ADDR )
X+ #define proc_addr(n) (pproc_addr + NR_TASKS)[(n)]
X+ #define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
X+ #define proc_number(p) ((p)->p_nr)
X+ 
X+ EXTERN struct proc proc[NR_TASKS + NR_PROCS];	/* process table */
X+ EXTERN struct proc *pproc_addr[NR_TASKS + NR_PROCS];
X+ 				/* ptrs to process table slots (fast) */
X  EXTERN struct proc *proc_ptr;	/* &proc[cur_proc] */
X***************
X*** 45,48 ****
X  EXTERN struct proc *rdy_tail[NQ];	/* pointers to ready list tails */
X- 
X- EXTERN unsigned busy_map;		/* bit map of busy tasks */
X- EXTERN message *task_mess[NR_TASKS+1];	/* ptrs to messages for busy tasks */
X--- 79 ----
END_OF_FILE
if test 4435 -ne `wc -c <'kerneldif/proc.h.cdif'`; then
    echo shar: \"'kerneldif/proc.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/proc.h.cdif'
fi
if test -f 'kerneldif/protect.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/protect.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/protect.h.cdif'\" \(5010 characters\)
sed "s/^X//" >'kerneldif/protect.h.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/protect.h	Fri Mar 24 01:52:27 1989
X***************
X*** 0 ****
X--- 1,104 ----
X+ /* 286 software constants. */
X+ 
X+ /* Table sizes. */
X+ #define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) /* spec. and LDT's */
X+ #define IDT_SIZE (IRQ8_VECTOR + 8)	/* only up to the highest vector */
X+ #define LDT_SIZE         2	/* contains CS and DS only */
X+ 
X+ /* Fixed global descriptors; 1 to 7 are prescribed by the BIOS. */
X+ #define GDT_INDEX        1	/* temp spot to store pointer to GDT */
X+ #define IDT_INDEX        2	/* temp spot to store pointer to GDT */
X+ #define DS_INDEX         3	/* kernel DS */
X+ #define ES_INDEX         4	/* kernel ES */
X+ #define SS_INDEX         5	/* kernel SS */
X+ #define CS_INDEX         6	/* kernel CS */
X+ #define BIOS_CS_INDEX    7	/* temp for BIOS */
X+ #define TSS_INDEX        8	/* kernel TSS */
X+ #define DB_TSS_INDEX     9	/* debugger TSS */
X+ #define DS_286_INDEX    10	/* scratch source segment for klib286 */
X+ #define ES_286_INDEX    11	/* scratch destination segment for klib286 */
X+ #define COLOR_INDEX     12	/* color screen segment */
X+ #define MONO_INDEX      13	/* mono screen segment */
X+ 				/* the next 2 only work for 386's but are
X+ 				 * reserved for debugging 286 code on 386's
X+ 				 */
X+ #define REAL_CS_INDEX   14	/* kernel CS suitable for real mode switch */
X+ #define REAL_DS_INDEX   15	/* kernel DS suitable for real mode switch */
X+ #define FIRST_LDT_INDEX 16
X+ 
X+ #define GDT_SELECTOR      0x08	/* (GDT_INDEX * DESC_SIZE) bad for asld */
X+ #define IDT_SELECTOR      0x10	/* (IDT_INDEX * DESC_SIZE) */
X+ #define DS_SELECTOR       0x18	/* (DS_INDEX * DESC_SIZE) */
X+ #define CS_SELECTOR       0x30	/* (CS_INDEX * DESC_SIZE) */
X+ #define BIOS_CS_SELECTOR  0x38	/* (BIOS_CS_INDEX * DESC_SIZE) */
X+ #define TSS_SELECTOR      0x40	/* (TSS_INDEX * DESC_SIZE) */
X+ #define DB_TSS_SELECTOR   0x48	/* (DB_TSS_INDEX * DESC_SIZE) */
X+ #define DS_286_SELECTOR   0x51	/* (DS_286_INDEX * DESC_SIZE + 1) */
X+ #define ES_286_SELECTOR   0x59	/* (DS_286_INDEX * DESC_SIZE + 1) */
X+ #define COLOR_SELECTOR    0x61	/* (COLOR_INDEX * DESC_SIZE + 1) */
X+ #define MONO_SELECTOR     0x69	/* (MONO_INDEX * DESC_SIZE + 1) */
X+ #define REAL_CS_SELECTOR  0x70	/* (REAL_CS_INDEX * DESC_SIZE) */
X+ #define REAL_DS_SELECTOR  0x78	/* (REAL_DS_INDEX * DESC_SIZE) */
X+ 
X+ /* Fixed local descriptors. */
X+ #define CS_LDT_INDEX     0	/* process CS */
X+ #define DS_LDT_INDEX     1	/* process DS=ES=FS=GS=SS */
X+ 
X+ /* Privileges. */
X+ #define INTR_PRIVILEGE   0	/* kernel and interrupt handlers */
X+ #define TASK_PRIVILEGE   1
X+ #define USER_PRIVILEGE   3
X+ 
X+ /* 286 hardware constants. */
X+ 
X+ /* Exception vector numbers. */
X+ #define BOUNDS_VECTOR       5	/* bounds check failed */
X+ #define INVAL_OP_VECTOR     6	/* invalid opcode */
X+ #define COPROC_NOT_VECTOR   7	/* coprocessor not available */
X+ #define DOUBLE_FAULT_VECTOR 8
X+ #define COPROC_SEG_VECTOR   9	/* coprocessor segment overrun */
X+ #define INVAL_TSS_VECTOR   10	/* invalid TSS */
X+ #define SEG_NOT_VECTOR     11	/* segment not present */
X+ #define STACK_FAULT_VECTOR 12	/* stack exception */
X+ #define PROTECTION_VECTOR  13	/* general protection */
X+ 
X+ /* Selector bits. */
X+ #define TI            0x04	/* table indicator */
X+ #define RPL           0x03	/* requester privilege level */
X+ 
X+ /* Descriptor structure offsets. */
X+ #define DESC_BASE        2	/* to base_low */
X+ #define DESC_BASE_MIDDLE 4	/* to base_middle */
X+ #define DESC_ACCESS	 5	/* to access byte */
X+ #define DESC_SIZE        8	/* sizeof (struct segdesc_s) */
X+ 
X+ /* Segment sizes. */
X+ #define MAX_286_SEG_SIZE 0x10000L
X+ #define REAL_SEG_SIZE    0x10000L
X+ 
X+ /* Base and limit sizes and shifts. */
X+ #define BASE_MIDDLE_SHIFT   16	/* shift for base --> base_middle */
X+ 
X+ /* Access-byte and type-byte bits. */
X+ #define PRESENT       0x80	/* set for descriptor present */
X+ #define DPL           0x60	/* descriptor privilege level mask */
X+ #define DPL_SHIFT        5
X+ #define SEGMENT       0x10	/* set for segment-type descriptors */
X+ 
X+ /* Access-byte bits. */
X+ #define EXECUTABLE    0x08	/* set for executable segment */
X+ #define CONFORMING    0x04	/* set for conforming segment if executable */
X+ #define EXPAND_DOWN   0x04	/* set for expand-down segment if !executab */
X+ #define READABLE      0x02	/* set for readable segment if executable */
X+ #define WRITEABLE     0x02	/* set for writeable segment if !executable */
X+ #define TSS_BUSY      0x02	/* set if TSS descriptor is busy */
X+ #define ACCESSED      0x01	/* set if segment accessed */
X+ 
X+ /* Special descriptor types. */
X+ #define AVL_286_TSS      1	/* available 286 TSS */
X+ #define LDT              2	/* local descriptor table */
X+ #define BUSY_286_TSS     3	/* set transparently to the software */
X+ #define CALL_286_GATE    4	/* not used */
X+ #define TASK_GATE        5	/* only used by debugger */
X+ #define INT_286_GATE     6	/* interrupt gate, used for all vectors */
X+ #define TRAP_286_GATE    7	/* not used */
END_OF_FILE
if test 5010 -ne `wc -c <'kerneldif/protect.h.cdif'`; then
    echo shar: \"'kerneldif/protect.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/protect.h.cdif'
fi
if test -f 'kerneldif/type.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/type.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/type.h.cdif'\" \(2827 characters\)
sed "s/^X//" >'kerneldif/type.h.cdif' <<'END_OF_FILE'
X*** kernel-1.3/type.h	Wed Aug  3 21:18:39 1988
X--- kernel/type.h	Sun Mar 12 18:45:14 1989
X***************
X*** 1,22 ****
X! /* The 'pc_psw' struct is machine dependent.  It must contain the information
X!  * pushed onto the stack by an interrupt, in the same format as the hardware
X!  * creates and expects.  It is used for storing the interrupt status after a
X!  * trap or interrupt, as well as for causing interrupts for signals.
X!  */
X! 
X! #ifdef i8088
X! struct pc_psw {
X!   int (*pc)();			/* storage for program counter */
X!   phys_clicks cs;		/* code segment register */
X!   unsigned psw;			/* program status word */
X! };
X! 
X! /* This struct is used to build data structure pushed by kernel upon signal. */
X! struct sig_info {
X!   int signo;			/* sig number at end of stack */
X!   struct pc_psw sigpcpsw;
X! };
X! #endif
X! 
X! PUBLIC struct tasktab {
X  	int	(*initial_pc)();
X--- 1,2 ----
X! struct tasktab {
X  	int	(*initial_pc)();
X***************
X*** 25 ****
X--- 5,58 ----
X  };
X+ 
X+ #ifdef i8088
X+ 
X+ /* The u.._t types and their derivatives are used (only) when the precise
X+  * size must be specified for alignment of machine-dependent structures.
X+  * The offset_t type is the promotion of the smallest unsigned type large
X+  * enough to hold all machine offsets.  The phys_bytes type is not right
X+  * since it is signed, so will break on future 386 systems which have real
X+  * or virtual memory in the top half of the address space. Also, signed
X+  * remainders and divisions by powers of 2 cannot be done as efficiently.
X+  */
X+ typedef unsigned long offset_t;	/* machine offset */
X+ typedef unsigned char u8_t;	/* unsigned 8 bits */
X+ typedef unsigned short u16_t;	/* unsigned 16 bits */
X+ typedef unsigned long u32_t;	/* unsigned 32 bits */
X+ 
X+ /* The stack frame layout is determined by the software, but for efficiency
X+  * it is laid out so the assembly code to use it is as simple as possible.
X+  * 80286 protected mode and all real modes use the same frame, built with
X+  * 16-bit registers.  Real mode lacks an automatic stack switch, so little
X+  * is lost by using the 286 frame for it.
X+  */
X+ union stackframe_u {
X+   struct {
X+ 	u16_t es;
X+ 	u16_t ds;
X+ 	u16_t di;		/* di through cx are not accessed in C */
X+ 	u16_t si;		/* order is to match pusha/popa */
X+ 	u16_t bp;
X+ 	u16_t st;		/* hole for another copy of sp */
X+ 	u16_t bx;
X+ 	u16_t dx;
X+ 	u16_t cx;
X+ 	u16_t retreg;		/* ax */
X+ 	u16_t retadr;		/* return address for assembly code save() */
X+ 	u16_t pc;		/* interrupt pushes rest of frame */
X+ 	u16_t cs;
X+ 	u16_t psw;
X+ 	u16_t sp;
X+ 	u16_t ss;
X+   } r16;
X+ };
X+ 
X+ #ifdef i80286
X+ struct segdesc_s {		/* segment descriptor */
X+   u16_t limit_low;
X+   u16_t base_low;
X+   u8_t base_middle;
X+   u8_t access;			/* |P|DL|1|X|E|R|A| */
X+   u16_t reserved;
X+ };
X+ #endif /* i80286 */
X+ #endif /* i8088 */
END_OF_FILE
if test 2827 -ne `wc -c <'kerneldif/type.h.cdif'`; then
    echo shar: \"'kerneldif/type.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/type.h.cdif'
fi
echo shar: End of archive 7 \(of 10\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!agate!helios.ee.lbl.gov!ncis.tis.llnl.gov!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 8 - By Bruce Evans
Message-ID: <5270@ditmela.oz>
Date: 18 May 89 01:27:00 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1499


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 8 (of 10)."
# Contents:  kerneldif/protect.c.cdif kerneldif/rs2.x.cdif
#   kerneldif/rs232.c.cdif kerneldif/sconst.h.cdif
#   kerneldif/sglo.h.cdif kerneldif/xt_wini.c.cdif libdif/head.s.cdif
#   toolsdif/fsck1.s.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:29 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/protect.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/protect.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/protect.c.cdif'\" \(9757 characters\)
sed "s/^X//" >'kerneldif/protect.c.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/protect.c	Fri Mar 24 01:58:15 1989
X***************
X*** 0 ****
X--- 1,309 ----
X+ /* This file contains most of the static initialization for protected mode
X+  * (some is done in mpx286.x), and routines to initialize the code and data
X+  * segment descriptors for new processes.
X+  */
X+ 
X+ #include "../h/const.h"
X+ #include "../h/type.h"
X+ #include "const.h"
X+ #include "type.h"
X+ #include "glo.h"
X+ #include "proc.h"
X+ #include "protect.h"
X+ 
X+ struct desctableptr_s {
X+   u16_t limit;
X+   u32_t base;			/* really u24_t + pad for 286 */
X+ };
X+ 
X+ struct gatedesc_s {
X+   u16_t offset_low;
X+   u16_t selector;
X+   u8_t pad;			/* |000|XXXXX| ig & trpg, |XXXXXXXX| task g */
X+   u8_t p_dpl_type;		/* |P|DL|0|TYPE| */
X+   u16_t reserved;
X+ };
X+ 
X+ struct tss286_s {
X+   u16_t backlink;
X+   u16_t sp0;
X+   u16_t ss0;
X+   u16_t sp1;
X+   u16_t ss1;
X+   u16_t sp2;
X+   u16_t ss2;
X+   u16_t ip;
X+   u16_t flags;
X+   u16_t ax;
X+   u16_t cx;
X+   u16_t dx;
X+   u16_t bx;
X+   u16_t sp;
X+   u16_t bp;
X+   u16_t si;
X+   u16_t di;
X+   u16_t es;
X+   u16_t cs;
X+   u16_t ss;
X+   u16_t ds;
X+   u16_t ldt;
X+ };
X+ 
X+ union tss_u {
X+   struct tss286_s t2;
X+ };
X+ 
X+ /* PRIVATE int gdt_pad = 0;	/* attempt to align gdt on long boundary */
X+ PUBLIC struct segdesc_s gdt[GDT_SIZE] = { 0, };
X+ 				/* temporary initialize it to get it in data
X+ 				 * segment for better control over alignment
X+ 				 */
X+ PRIVATE struct gatedesc_s idt[IDT_SIZE];  /* zero-init so none present */
X+ PUBLIC union tss_u tss;		/* zero init */
X+ 
X+ #ifdef DEBUGGER
X+ #define IF 0x0200
X+ PUBLIC union tss_u db_tss;	/* zero init */
X+ extern char db_stacktop[];
X+ #endif
X+ 
X+ extern void divide_error();
X+ extern void debug2_exception();
X+ extern void debug3_exception();
X+ extern void nmi();
X+ extern void breakpoint();
X+ extern void overflow();
X+ extern void bounds_check();
X+ extern void inval_opcode();
X+ extern void copr_not_available();
X+ extern void double_fault();
X+ extern void copr_seg_overrun();
X+ extern void inval_tss();
X+ extern void segment_not_present();
X+ extern void stack_exception();
X+ extern void general_protection();
X+ extern void page_fault();
X+ extern void copr_error();
X+ 
X+ extern void clock_int();
X+ extern void tty_int();
X+ extern void psecondary_int();
X+ extern void prs232_int();
X+ extern void disk_int();
X+ extern void lpr_int();
X+ extern void wini_int();
X+ 
X+ extern void p2_s_call();
X+ extern void p3_s_call();
X+ 
X+ FORWARD void sdesc();
X+ FORWARD void task_gate();
X+ 
X+ PRIVATE void int_gate( vec_nr, base, dpl_type )
X+ unsigned vec_nr;
X+ offset_t base;
X+ unsigned dpl_type;
X+ {
X+   /* Build descriptor for an interrupt gate. */
X+ 
X+   register struct gatedesc_s *idp;
X+ 
X+   idp = &idt[vec_nr];
X+   idp->offset_low = base;
X+   idp->selector = CS_SELECTOR;
X+   idp->p_dpl_type = dpl_type;
X+ }
X+ 
X+ PUBLIC void init_codeseg( segdp, base, size, privilege )
X+ register struct segdesc_s *segdp;
X+ offset_t base;
X+ offset_t size;
X+ int privilege;
X+ {
X+   /* Build descriptor for a code segment. */
X+ 
X+   sdesc( segdp, base, size );
X+   segdp->access = (privilege << DPL_SHIFT)
X+ 		| (PRESENT | SEGMENT | EXECUTABLE | READABLE);
X+ 		/* CONFORMING = 0, ACCESSED = 0 */
X+ }
X+ 
X+ PUBLIC void init_dataseg( segdp, base, size, privilege )
X+ register struct segdesc_s *segdp;
X+ offset_t base;
X+ offset_t size;
X+ int privilege;
X+ {
X+   /* Build descriptor for a data segment. */
X+ 
X+   sdesc( segdp, base, size );
X+   segdp->access = (privilege << DPL_SHIFT) | (PRESENT | SEGMENT | WRITEABLE);
X+ 		/* EXECUTABLE = 0, EXPAND_DOWN = 0, ACCESSED = 0 */
X+ }
X+ 
X+ PUBLIC void prot_init()
X+ {
X+   /* Set up tables for protected mode, even if they will not be used.
X+    * All GDT slots are allocated at compile time.
X+    */
X+ 
X+   offset_t codebase;
X+   offset_t code_bytes;
X+   offset_t database;
X+   offset_t data_bytes;
X+   int gate_nr;
X+   u8_t type3_bit;
X+   unsigned ldt_selector;
X+   register struct proc *rp;
X+ 
X+   static struct
X+   {
X+     unsigned vec_nr;
X+     void (*gate)();
X+   }
X+   gate_table[] =
X+   {
X+     DIVIDE_VECTOR, divide_error,
X+     NMI_VECTOR, nmi,
X+     OVERFLOW_VECTOR, overflow,
X+     BOUNDS_VECTOR, bounds_check,
X+     INVAL_OP_VECTOR, inval_opcode,
X+     COPROC_NOT_VECTOR, copr_not_available,
X+     DOUBLE_FAULT_VECTOR, double_fault,
X+     COPROC_SEG_VECTOR, copr_seg_overrun,
X+     INVAL_TSS_VECTOR, inval_tss,
X+     SEG_NOT_VECTOR, segment_not_present,
X+     STACK_FAULT_VECTOR, stack_exception,
X+     PROTECTION_VECTOR, general_protection,
X+     IRQ0_VECTOR + CLOCK_IRQ, clock_int,
X+     IRQ0_VECTOR + KEYBOARD_IRQ, tty_int,
X+     IRQ0_VECTOR + SECONDARY_IRQ, psecondary_int,
X+     IRQ0_VECTOR + RS232_IRQ, prs232_int,
X+     IRQ0_VECTOR + FLOPPY_IRQ, disk_int,
X+     IRQ0_VECTOR + PRINTER_IRQ, lpr_int,
X+     IRQ8_VECTOR + AT_WINI_IRQ - 8, wini_int,
X+   };
X+ 
X+   /* This is called early and can't use tables set up by main(). */
X+   codebase = (offset_t) codeseg() << HCLICK_SHIFT;
X+   database = (offset_t) dataseg() << HCLICK_SHIFT;
X+   data_bytes = (offset_t) sizes[1] << CLICK_SHIFT;
X+   if (sizes[0] == 0)
X+     code_bytes = data_bytes;	/* common I&D */
X+   else
X+     code_bytes = (offset_t) sizes[0] << CLICK_SHIFT;
X+ 
X+   /* Build temporary gdt and idt pointers in GDT where BIOS needs them. */
X+   ((struct desctableptr_s *) &gdt[GDT_INDEX])->limit = sizeof gdt - 1;
X+   ((struct desctableptr_s *) &gdt[GDT_INDEX])->base =
X+ 					       database + (offset_t) gdt;
X+   ((struct desctableptr_s *) &gdt[IDT_INDEX])->limit = sizeof idt - 1;
X+   ((struct desctableptr_s *) &gdt[IDT_INDEX])->base =
X+ 					       database + (offset_t) idt;
X+ 
X+   /* Build segment descriptors for tasks and interrupt handlers. */
X+   init_dataseg( &gdt[DS_INDEX], database, data_bytes, INTR_PRIVILEGE );
X+   init_dataseg( &gdt[ES_INDEX], database, data_bytes, INTR_PRIVILEGE );
X+   init_dataseg( &gdt[SS_INDEX], database, data_bytes, INTR_PRIVILEGE );
X+   init_codeseg( &gdt[CS_INDEX], codebase, code_bytes, INTR_PRIVILEGE );
X+ 
X+   /* Build scratch descriptors for functions in klib286. */
X+   init_dataseg( &gdt[DS_286_INDEX], (offset_t) 0, (offset_t) MAX_286_SEG_SIZE,
X+ 		TASK_PRIVILEGE );
X+   init_dataseg( &gdt[ES_286_INDEX], (offset_t) 0, (offset_t) MAX_286_SEG_SIZE,
X+ 		TASK_PRIVILEGE );
X+ 
X+   /* Build descriptors for video segments. */
X+   init_dataseg( &gdt[COLOR_INDEX], (offset_t) COLOR_BASE,
X+ 		(offset_t) COLOR_SIZE, TASK_PRIVILEGE );
X+   init_dataseg( &gdt[MONO_INDEX], (offset_t) MONO_BASE,
X+ 		(offset_t) MONO_SIZE, TASK_PRIVILEGE );
X+ 
X+   /* Build segment descriptors for switching to real mode.
X+    * They are only used by the debugger, which only works on 386's.
X+    */
X+   init_codeseg( &gdt[REAL_CS_INDEX], codebase, (offset_t) REAL_SEG_SIZE,
X+ 		INTR_PRIVILEGE );
X+   init_dataseg( &gdt[REAL_DS_INDEX], database, (offset_t) REAL_SEG_SIZE,
X+ 		INTR_PRIVILEGE );
X+ 
X+   /* Build main TSS.  This is used only to record the stack pointer to
X+    * be used after an interrupt.  This pointer is set up so that an
X+    * interrupt automatically saves the current process' registers
X+    * eip:cs:ef:esp:ss in the correct slots in the process table.
X+    */
X+   tss.t2.ss0 = DS_SELECTOR;
X+   type3_bit = 0;
X+   init_dataseg( &gdt[TSS_INDEX], database + (offset_t) &tss,
X+ 		(offset_t) sizeof tss, INTR_PRIVILEGE );
X+   gdt[TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT)
X+ 			  | AVL_286_TSS | type3_bit;
X+ 
X+ #ifdef DEBUGGER
X+   /* Build TSS and task gates for debugger. */
X+   init_dataseg( &gdt[DB_TSS_INDEX], database + (offset_t) &db_tss,
X+ 		(offset_t) sizeof db_tss, INTR_PRIVILEGE );
X+   gdt[DB_TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT)
X+ 			     | AVL_286_TSS | type3_bit;
X+   task_gate( &idt[DEBUG_VECTOR], DB_TSS_SELECTOR, USER_PRIVILEGE );
X+   task_gate( &idt[BREAKPOINT_VECTOR], DB_TSS_SELECTOR, USER_PRIVILEGE );
X+   db_tss.t2.cs = CS_SELECTOR;
X+   db_tss.t2.ip = (u16_t) debug2_exception;
X+   db_tss.t2.flags = INIT_PSW & ~IF;
X+   db_tss.t2.ds =
X+   db_tss.t2.es =
X+   db_tss.t2.ss = DS_SELECTOR;
X+   db_tss.t2.sp = (u16_t) db_stacktop;
X+ #endif
X+ 
X+   /* Build local descriptors in GDT for LDT's in process table.
X+    * The LDT's are allocated at compile time in the process table, and
X+    * initialized whenever a process' map is initialized or changed.
X+    */
X+   for ( rp = BEG_PROC_ADDR, ldt_selector = FIRST_LDT_INDEX * DESC_SIZE;
X+ 	rp < END_PROC_ADDR; ++rp, ldt_selector += DESC_SIZE )
X+   {
X+     init_dataseg( &gdt[ldt_selector / DESC_SIZE],
X+ 		  database + (offset_t) rp->p_ldt,
X+ 		  (offset_t) sizeof rp->p_ldt, INTR_PRIVILEGE );
X+     gdt[ldt_selector / DESC_SIZE].access = PRESENT | LDT;
X+     rp->p_ldt_sel = ldt_selector;
X+   }
X+ 
X+   /* Build descriptors for interrupt gates in IDT. */
X+   for ( gate_nr = 0; gate_nr < sizeof gate_table / sizeof gate_table[0];
X+ 	++gate_nr )
X+   {
X+     int_gate( gate_table[gate_nr].vec_nr, (offset_t) gate_table[gate_nr].gate,
X+ 	      PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) |
X+ 	      INT_286_GATE | type3_bit );
X+   }
X+   int_gate( SYS_VECTOR, (offset_t)
X+ 	    p2_s_call,
X+ 	    PRESENT | (USER_PRIVILEGE << DPL_SHIFT) |
X+ 	    INT_286_GATE | type3_bit );
X+ }
X+ 
X+ PRIVATE void sdesc( segdp, base, size )
X+ register struct segdesc_s *segdp;
X+ offset_t base;
X+ offset_t size;
X+ {
X+   /* Fill in size fields (base and limit) of a descriptor. */
X+ 
X+   segdp->base_low = base;
X+   segdp->base_middle = base >> BASE_MIDDLE_SHIFT;
X+   segdp->limit_low = size - 1;
X+ }
X+ 
X+ PRIVATE void task_gate( gatedp, selector, privilege )
X+ register struct gatedesc_s *gatedp;
X+ unsigned selector;
X+ int privilege;
X+ {
X+   /* Build descriptor for a task gate. */
X+ 
X+   gatedp->selector = selector;
X+   gatedp->p_dpl_type = (privilege << DPL_SHIFT) | PRESENT | TASK_GATE;
X+ 		     /* SEGMENT = 0 */
X+ }
END_OF_FILE
if test 9757 -ne `wc -c <'kerneldif/protect.c.cdif'`; then
    echo shar: \"'kerneldif/protect.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/protect.c.cdif'
fi
if test -f 'kerneldif/rs2.x.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/rs2.x.cdif'\"
else
echo shar: Extracting \"'kerneldif/rs2.x.cdif'\" \(6495 characters\)
sed "s/^X//" >'kerneldif/rs2.x.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/rs2.x	Sun Mar 12 15:27:29 1989
X***************
X*** 0 ****
X--- 1,304 ----
X+ |*===========================================================================*
X+ |*		rs232 interrupt handlers for real and protected modes	     *
X+ |*===========================================================================*
X+ 
X+ #include "../h/const.h"
X+ #include "const.h"
X+ #include "sconst.h"
X+ #define RS2 .define
X+ #include "sglo.h"
X+ 
X+ #undef MINOR
X+ 
X+ #ifdef ASLD
X+ #define add1_and_align(n)	[[[n]+1+1] / 2 * 2]	/* word alignment */
X+ #else
X+ #define add1_and_align(n)	(((n)+1+1) & !1)
X+ #endif
X+ 
X+ | These constants are defined in tty.h. That has C stuff so can't be included.
X+ EVENT_THRESHOLD		=	64
X+ RS_IBUFSIZE		=	128
X+ 
X+ | These constants are defined in rs232.c.
X+ IS_LINE_STATUS_CHANGE	=	6
X+ IS_MODEM_STATUS_CHANGE	=	0
X+ IS_NO_INTERRUPT		=	1
X+ IS_RECEIVER_READY	=	4
X+ IS_TRANSMITTER_READY	=	2
X+ LS_OVERRUN_ERR		=	2
X+ LS_PARITY_ERR		=	4
X+ LS_FRAMING_ERR		=	8
X+ LS_BREAK_INTERRUPT	=	0x10
X+ LS_TRANSMITTER_READY	=	0x20
X+ MC_DTR			=	1
X+ MC_OUT2			=	8
X+ MS_CTS			=	0x10
X+ ODEVREADY		=	MS_CTS
X+ ODONE			=	1
X+ OQUEUED			=	0x20
X+ ORAW			=	2
X+ OSWREADY		=	0x40
X+ OWAKEUP			=	4
X+ RS_IHIGHWATER		=	3*RS_IBUFSIZE/4
X+ 
X+ | These port offsets are hard-coded in rs232.c.
X+ XMIT_OFFSET		=	0
X+ RECV_OFFSET		=	0
X+ INT_ID_OFFSET		=	2
X+ MODEM_CTL_OFFSET	=	4
X+ LINE_STATUS_OFFSET	=	5
X+ MODEM_STATUS_OFFSET	=	6
X+ 
X+ | Offsets in struct rs232_s. They must match rs232.c
X+ MINOR			=	0
X+ IDEVREADY		=	MINOR+2
X+ ITTYREADY		=	IDEVREADY+1
X+ IBUF			=	add1_and_align(ITTYREADY)
X+ IBUFEND			=	IBUF+2
X+ IHIGHWATER		=	IBUFEND+2
X+ IPTR			=	IHIGHWATER+2
X+ OSTATE			=	IPTR+2
X+ OXOFF			=	OSTATE+1
X+ OBUFEND			=	add1_and_align(OXOFF)
X+ OPTR			=	OBUFEND+2
X+ XMIT_PORT		=	OPTR+2
X+ RECV_PORT		=	XMIT_PORT+2
X+ DIV_LOW_PORT		=	RECV_PORT+2
X+ DIV_HI_PORT		=	DIV_LOW_PORT+2
X+ INT_ENAB_PORT		=	DIV_HI_PORT+2
X+ INT_ID_PORT		=	INT_ENAB_PORT+2
X+ LINE_CTL_PORT		=	INT_ID_PORT+2
X+ MODEMCTL_PORT		=	LINE_CTL_PORT+2
X+ LINESTATUS_PORT		=	MODEMCTL_PORT+2
X+ MODEMSTATUS_PORT	=	LINESTATUS_PORT+2
X+ LSTATUS			=	MODEMSTATUS_PORT+2
X+ FRAMING_ERRORS		=	add1_and_align(LSTATUS)
X+ OVERRUN_ERRORS		=	FRAMING_ERRORS+2
X+ PARITY_ERRORS		=	OVERRUN_ERRORS+2
X+ BREAK_INTERRUPTS	=	PARITY_ERRORS+2
X+ IBUF1			=	BREAK_INTERRUPTS+2
X+ IBUF2			=	IBUF1+RS_IBUFSIZE+1
X+ SIZEOF_STRUCT_RS232_S	=	IBUF2+RS_IBUFSIZE+1
X+ 
X+ 	.text
X+ 
X+ #ifdef i80286
X+ | PUBLIC void interrupt _psecondary_int();
X+ 
X+ _psecondary_int:
X+ 	push	ds
X+ 	push	si
X+ 	mov	si,ss
X+ 	mov	ds,si
X+ 	mov	si,#_rs_lines+SIZEOF_STRUCT_RS232_S
X+ 	j	commonp
X+ #endif
X+ 
X+ | PUBLIC void interrupt _secondary_int();
X+ 
X+ _secondary_int:
X+ 	push	ds
X+ 	push	si
X+ 	mov	si,#_rs_lines+SIZEOF_STRUCT_RS232_S
X+ 	j	common
X+ 
X+ #ifdef i80286
X+ | PUBLIC void interrupt _prs232_int();
X+ 
X+ _prs232_int:
X+ 	push	ds
X+ 	push	si
X+ 	mov	si,ss
X+ 	mov	ds,si
X+ 	mov	si,#_rs_lines
X+ 	j	commonp
X+ #endif
X+ 
X+ | input interrupt
X+ 
X+ inint:
X+ 	addb	dl,#RECV_OFFSET-INT_ID_OFFSET
X+ 	in
X+ 	mov	bx,IPTR(si)
X+ 	movb	(bx),al
X+ 	cmp	bx,IBUFEND(si)
X+ 	jge	checkxoff
X+ 	inc	_tty_events
X+ 	inc	bx
X+ 	mov	IPTR(si),bx
X+ 	cmp	bx,IHIGHWATER(si)
X+ 	jne	checkxoff
X+ 	addb	dl,#MODEM_CTL_OFFSET-RECV_OFFSET
X+ 	movb	al,#MC_OUT2+MC_DTR
X+ 	out
X+ 	movb	IDEVREADY(si),#FALSE
X+ checkxoff:
X+ 	testb	ah,#ORAW
X+ 	jne	rsnext
X+ 	cmpb	al,OXOFF(si)
X+ 	je	gotxoff
X+ 	testb	ah,#OSWREADY
X+ 	jne	rsnext
X+ 	orb	ah,#OSWREADY
X+ 	mov	dx,LINESTATUS_PORT(si)
X+ 	in
X+ 	testb	al,#LS_TRANSMITTER_READY
X+ 	je	rsnext
X+ 	addb	dl,#XMIT_OFFSET-LINE_STATUS_OFFSET
X+ 	j	outint1
X+ 
X+ gotxoff:
X+ 	andb	ah,#notop(OSWREADY)
X+ 	j	rsnext
X+ 
X+ | PUBLIC void interrupt rs232_int();
X+ 
X+ _rs232_int:
X+ 	push	ds
X+ 	push	si
X+ 	mov	si,#_rs_lines
X+ common:
X+ 	seg	cs
X+ 	mov	ds,kernel_ds
X+ 	seg	cs
X+ commonp:
X+ 	push	ax
X+ 	push	bx
X+ 	push	dx
X+ 	movb	ah,OSTATE(si)
X+ 	mov	dx,INT_ID_PORT(si)
X+ 	in
X+ rsmore:
X+ 	cmpb	al,#IS_RECEIVER_READY
X+ 	je	inint
X+ 	cmpb	al,#IS_TRANSMITTER_READY
X+ 	je	outint
X+ 	cmpb	al,#IS_MODEM_STATUS_CHANGE
X+ 	je	modemint
X+ 	cmpb	al,#IS_LINE_STATUS_CHANGE
X+ 	jne	rsdone		| fishy
X+ 
X+ | line status change interrupt
X+ 
X+ 	addb	dl,#LINE_STATUS_OFFSET-INT_ID_OFFSET
X+ 	in
X+ 	testb	al,#LS_FRAMING_ERR
X+ 	je	over_framing_error
X+ 	inc	FRAMING_ERRORS(si)	
X+ over_framing_error:
X+ 	testb	al,#LS_OVERRUN_ERR
X+ 	je	over_overrun_error
X+ 	inc	OVERRUN_ERRORS(si)	
X+ over_overrun_error:
X+ 	testb	al,#LS_PARITY_ERR
X+ 	je	over_parity_error
X+ 	inc	PARITY_ERRORS(si)
X+ over_parity_error:
X+ 	testb	al,#LS_BREAK_INTERRUPT
X+ 	je	over_break_interrupt
X+ 	inc	BREAK_INTERRUPTS(si)
X+ over_break_interrupt:
X+ 
X+ rsnext:
X+ 	mov	dx,INT_ID_PORT(si)
X+ 	in
X+ 	cmpb	al,#IS_NO_INTERRUPT
X+ 	jne	rsmore
X+ rsdone:
X+ 	movb	al,#ENABLE
X+ 	out	INT_CTL
X+ 	testb	ah,#OWAKEUP
X+ 	jne	owakeup
X+ 	movb	OSTATE(si),ah
X+ 	pop	dx
X+ 	pop	bx
X+ 	pop	ax
X+ 	pop	si
X+ 	pop	ds
X+ rs2_iret:
X+ 	iret			| changed to iretd for 386 protected mode
X+ 	nop			| space for longer opcode
X+ 	nop			| padding since convenient to change 3 bytes
X+ 
X+ | output interrupt
X+ 
X+ outint:
X+ 	addb	dl,#XMIT_OFFSET-INT_ID_OFFSET
X+ outint1:
X+ 	cmpb	ah,#ODEVREADY+OQUEUED+OSWREADY
X+ 	jb	rsnext		| not all are set
X+ 	mov	bx,OPTR(si)
X+ 	movb	al,(bx)
X+ 	out
X+ 	inc	bx
X+ 	mov	OPTR(si),bx
X+ 	cmp	bx,OBUFEND(si)
X+ 	jb	rsnext
X+ 	add	_tty_events,#EVENT_THRESHOLD
X+ 	xorb	ah,#ODONE+OQUEUED+OWAKEUP	| OQUEUED off, others on
X+ 	j	rsnext		| direct exit might lose interrupt
X+ 
X+ | modem status change interrupt
X+ 
X+ modemint:
X+ 	addb	dl,#MODEM_STATUS_OFFSET-INT_ID_OFFSET
X+ 	in
X+ 	testb	al,#MS_CTS
X+ 	jne	m_devready
X+ 	andb	ah,#notop(ODEVREADY)
X+ 	j	rsnext
X+ 
X+ m_devready:
X+ 	testb	ah,#ODEVREADY
X+ 	jne	rsnext
X+ 	orb	ah,#ODEVREADY
X+ 	addb	dl,#LINE_STATUS_OFFSET-MODEM_STATUS_OFFSET
X+ 	in
X+ 	testb	al,#LS_TRANSMITTER_READY
X+ 	je	rsnext
X+ 	addb	dl,#XMIT_OFFSET-LINE_STATUS_OFFSET
X+ 	j	outint1
X+ 
X+ | special exit for output just completed
X+ 
X+ owakeup:
X+ 	andb	ah,#notop(OWAKEUP)
X+ 	movb	OSTATE(si),ah
X+ 
X+ | determine mask bit (it would be better to precalculate it in the struct)
X+ 
X+ 	movb	ah,#SECONDARY_MASK
X+ 	cmp	si,#_rs_lines
X+ 	jne	got_rs_mask
X+ 	movb	ah,#RS232_MASK
X+ got_rs_mask:
X+ 	mov	rs_mask,ax	| save ax to clear later
X+ 	in	INT_CTLMASK
X+ 	orb	al,ah
X+ 	out	INT_CTLMASK
X+ 
X+ | rearrange context to call tty_wakeup()
X+ 
X+ 	pop	dx
X+ 	pop	bx
X+ 	pop	ax
X+ 	pop	si
X+ 	pop	ds
X+ 	call	save
X+ 	push	rs_mask		| save the mask again, reentrantly
X+ 	sti
X+ 	call	_tty_wakeup
X+ 	cli
X+ 	pop	ax
X+ 	notb	ah		| return this
X+ 	in	INT_CTLMASK
X+ 	andb	al,ah
X+ 	out	INT_CTLMASK
X+ 	ret
X+ 
X+ 
X+ 	.data
X+ rs_mask:
X+ 	.space	2
X+ 	.space	2		| align
END_OF_FILE
if test 6495 -ne `wc -c <'kerneldif/rs2.x.cdif'`; then
    echo shar: \"'kerneldif/rs2.x.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/rs2.x.cdif'
fi
if test -f 'kerneldif/rs232.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/rs232.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/rs232.c.cdif'\" \(3649 characters\)
sed "s/^X//" >'kerneldif/rs232.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/rs232.c	Fri Dec  9 02:21:32 1988
X--- kernel/rs232.c	Sun Mar 12 00:08:06 1989
X***************
X*** 173,174 ****
X--- 173,175 ----
X    interrupt(TTY, &rs232_rd_mess);	/* send a message to the tty task */
X+   lock();			/* new interrupt() may unlock() */
X  }
X***************
X*** 229,230 ****
X--- 230,232 ----
X  	interrupt(TTY, &rs232_wt_mess);	/* send the message to the tty task */
X+ 	lock();			/* new interrupt() may unlock() */
X    } else {
X***************
X*** 279,281 ****
X    char c, *limit;
X!   unsigned short segment, offset, offset1;
X    register struct rs_struct *rs;
X--- 281,283 ----
X    char c, *limit;
X!   unsigned long offset, offset1;
X    register struct rs_struct *rs;
X***************
X*** 290,293 ****
X    limit = &rs->rs_buf[RS_BUF_SIZE - SPARE];
X!   segment = (tp->tty_phys >> 4) & WORD_MASK;
X!   offset = tp->tty_phys & OFF_MASK;
X    offset1 = offset;
X--- 292,294 ----
X    limit = &rs->rs_buf[RS_BUF_SIZE - SPARE];
X!   offset = tp->tty_phys;
X    offset1 = offset;
X***************
X*** 296,298 ****
X    while (tp->tty_outleft > 0 && rs->rs_next + rs->rs_left < limit) {
X! 	c = get_byte(segment, offset);	/* fetch 1 byte */
X  	offset++;
X--- 297,299 ----
X    while (tp->tty_outleft > 0 && rs->rs_next + rs->rs_left < limit) {
X! 	c = get_phys_byte(offset);	/* fetch 1 byte */
X  	offset++;
X***************
X*** 322,324 ****
X   *===========================================================================*/
X! PRIVATE rs_out_char(tp, c)
X  register struct tty_struct *tp;	/* pointer to tty struct */
X--- 323,325 ----
X   *===========================================================================*/
X! PUBLIC rs_out_char(tp, c)
X  register struct tty_struct *tp;	/* pointer to tty struct */
X***************
X*** 420,425 ****
X  		caller = (int) tp->tty_outproc;
X- 		tty_reply(REVIVE, replyee, caller, tp->tty_cum, 0L, 0L);
X  		tp->tty_waiting = NOT_WAITING;
X  		output_done--;
X! 		restore(old_state);
X  		return(1);
X--- 421,426 ----
X  		caller = (int) tp->tty_outproc;
X  		tp->tty_waiting = NOT_WAITING;
X  		output_done--;
X! 		restore(old_state);	/* don't try to lock the reply */
X! 		tty_reply(REVIVE, replyee, caller, tp->tty_cum, 0L, 0L);
X  		return(1);
X***************
X*** 453,455 ****
X   *===========================================================================*/
X! PRIVATE	init_rs232()
X  {
X--- 454,456 ----
X   *===========================================================================*/
X! PUBLIC init_rs232()
X  {
X***************
X*** 491,492 ****
X--- 492,499 ----
X    }
X+ #if NR_RS_LINES > 0
X+     enable_irq( RS232_IRQ );
X+ #endif
X+ #if NR_RS_LINES > 1
X+     enable_irq( SECONDARY_IRQ );
X+ #endif
X  }
X***************
X*** 497,499 ****
X   *===========================================================================*/
X! PRIVATE set_uart(line, mode, speeds)
X  int line;			/* which line number (>= NR_CONS) */
X--- 504,506 ----
X   *===========================================================================*/
X! PUBLIC set_uart(line, mode, speeds)
X  int line;			/* which line number (>= NR_CONS) */
X***************
X*** 565,566 ****
X--- 572,604 ----
X    port_out(base + RS232_LINE_CONTROL, line_controls);
X+ }
X+ 
X+ 
X+ /* Kludges to get this old tty version to work with the protected kernel. */
X+ 
X+ PUBLIC rs232_1handler()
X+ {
X+   rs232(1);
X+ }
X+ 
X+ 
X+ PUBLIC rs232_2handler()
X+ {
X+   rs232(2);
X+ }
X+ 
X+ 
X+ PUBLIC tty_wakeup()
X+ {
X+ /* Wake up TTY after a timeout if there is something to flush. */
X+ 
X+ #define WAKEUP_TIMEOUT (8*HZ/60)
X+ 
X+   static unsigned wakeup_timeout = WAKEUP_TIMEOUT;
X+ 
X+   lock();
X+   if (flush_flag && --wakeup_timeout == 0) {
X+ 	wakeup_timeout = WAKEUP_TIMEOUT;
X+ 	rs_flush();
X+   }
X+   unlock();
X  }
END_OF_FILE
if test 3649 -ne `wc -c <'kerneldif/rs232.c.cdif'`; then
    echo shar: \"'kerneldif/rs232.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/rs232.c.cdif'
fi
if test -f 'kerneldif/sconst.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/sconst.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/sconst.h.cdif'\" \(5266 characters\)
sed "s/^X//" >'kerneldif/sconst.h.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/sconst.h	Sun Mar 26 01:22:20 1989
X***************
X*** 0 ****
X--- 1,168 ----
X+ /* Miscellaneous constants used in assembler code. */
X+ #define DS_286_OFFSET DS_286_INDEX*DESC_SIZE
X+ #define EM_MASK		0xFFF0	/* extended memory mask for hi word */
X+ #define ES_286_OFFSET ES_286_INDEX*DESC_SIZE
X+ #define HCHIGH_MASK	0x0F	/* h/w click mask for low byte of hi word */
X+ #define HCLOW_MASK	0xF0	/* h/w click mask for low byte of low word */
X+ #define Msize		12	/* size of a message in 16-bit words */
X+ #define OFF_MASK	0x000F	/* offset mask for long -> hclick:offset */
X+ #define TEST1PATTERN	0x55	/* memory test pattern 1 */
X+ #define TEST2PATTERN	0xAA	/* memory test pattern 2 */
X+ 
X+ /* Opcodes (used in patching). */
X+ #define IRET_OPCODE	0xCF
X+ #define JMP_OPCODE	0xE9
X+ #define NOP_OPCODE	0x90
X+ 
X+ /* BIOS numbers. */
X+ #define EM_XFER_VEC	0x15	/* copy (normal or extended) memory */
X+ #define EM_XFER_FUNC	0x87
X+ #define GET_EXTMEM_VEC	0x15	/* get extended memory size */
X+ #define GET_EXTMEM_FUNC	0x88
X+ #define GET_MEM_VEC	0x12	/* get memory size */
X+ #define SET_PROTECT_VEC	0x15	/* set protected mode */
X+ #define SET_PROTECT_FUNC 0x89
X+ 
X+ /* 8259 mask bits. */
X+ #define AT_WINI_MASK	0x40	/* (1 << (AT_WINI_IRQ & 0x07)), etc */
X+ #define CLOCK_MASK	0x01
X+ #define ETHER_MASK	0x08
X+ #define FLOPPY_MASK	0x40
X+ #define KEYBOARD_MASK	0x02
X+ #define PRINTER_MASK	0x80
X+ #define RS232_MASK	0x10
X+ #define SECONDARY_MASK	0x08
X+ #define XT_WINI_MASK	0x20
X+ 
X+ /* Offsets in struct proc. They MUST match proc.h. Use '=' to define them
X+  * instead of '#define', so they can be built cumulatively (for easy changes)
X+  * without producing large macro expansions.
X+  */
X+ #if 0 /* uurghh, the duplicated labels cause asld to run out of memory */
X+ P_STACKBASE	=	0
X+ ESREG		=	P_STACKBASE
X+ DSREG		=	ESREG + 2
X+ DIREG		=	DSREG + 2
X+ SIREG		=	DIREG + 2
X+ BPREG		=	SIREG + 2
X+ STREG		=	BPREG + 2	/* hole for another SP */
X+ BXREG		=	STREG + 2
X+ DXREG		=	BXREG + 2
X+ CXREG		=	DXREG + 2
X+ AXREG		=	CXREG + 2
X+ RETADR		=	AXREG + 2	/* return address for save() call */
X+ PCREG		=	RETADR + 2
X+ CSREG		=	PCREG + 2
X+ PSWREG		=	CSREG + 2
X+ SPREG		=	PSWREG + 2
X+ SSREG		=	SPREG + 2
X+ P_STACKTOP	=	SSREG + 2
X+ P_NR		=	P_STACKTOP
X+ P_LDT_SEL	=	P_NR + 2	/* assumes 16 bit ints */
X+ P_LDT		=	P_LDT_SEL + 2
X+ P_SPLIMIT	=	P_LDT_SEL + 16
X+ #endif
X+ 
X+ #define P_STACKBASE	0
X+ #define ESREG		0
X+ #define DSREG		2
X+ #define DIREG		4
X+ #define SIREG		6
X+ #define BPREG		8
X+ #define STREG		10	/* hole for another SP */
X+ #define BXREG		12
X+ #define DXREG		14
X+ #define CXREG		16
X+ #define AXREG		18
X+ #define RETADR		20	/* return address for save() call */
X+ #define PCREG		22
X+ #define CSREG		24
X+ #define PSWREG		26
X+ #define SPREG		28
X+ #define SSREG		30
X+ #define P_STACKTOP	32
X+ #define P_NR		32
X+ #define P_LDT_SEL	34	/* assumes 16 bit ints */
X+ #define P_LDT		36
X+ #define P_SPLIMIT	52
X+ 
X+ /* 286 tss offsets. */
X+ #define TSS2_S_BACKLINK	0
X+ #define TSS2_S_SP0	2
X+ #define TSS2_S_SS0	4
X+ #define TSS2_S_SP1	6
X+ #define TSS2_S_SS1	8
X+ #define TSS2_S_SP2	10
X+ #define TSS2_S_SS2	12
X+ #define TSS2_S_IP	14
X+ #define TSS2_S_FLAGS	16
X+ #define TSS2_S_AX	18
X+ #define TSS2_S_CX	20
X+ #define TSS2_S_DX	22
X+ #define TSS2_S_BX	24
X+ #define TSS2_S_SP	26
X+ #define TSS2_S_BP	28
X+ #define TSS2_S_SI	30
X+ #define TSS2_S_DI	32
X+ #define TSS2_S_ES	34
X+ #define TSS2_S_CS	36
X+ #define TSS2_S_SS	38
X+ #define TSS2_S_DS	40
X+ #define TSS2_S_LDT	42
X+ #define SIZEOF_TSS2_S	44
X+ 
X+ /* Macros to get some 8086 instructions through asld. */
X+ #ifdef ASLD
X+ #define callfar(s,o)	calli	o,s
X+ #define callfarptr(v)	calli	@v
X+ #define jmpfar(s,o)	jmpi	o,s
X+ #define jmpmem(adr)	jmp	@adr
X+ #define jmpreg(reg)	jmp	(reg)
X+ #define notop(n)	[-[n]-1]
X+ #define orop		+	/* used only if same as add */
X+ #else
X+ #define callfar(s,o)	call	s:o
X+ #define callfarptr(v)	call	far [v]
X+ #define jmpfar(s,o)	jmp	s:o
X+ #define jmpmem(adr)	jmp	adr
X+ #define jmpreg(reg)	jmp	reg
X+ #define notop(n)	(!(n))
X+ #define orop		\	/* don't expose '\' to end of line */
X+ #endif /* ASLD */
X+ 
X+ /* Macros to get some 286 instructions through asld.
X+  * Some are used without i80286.
X+  */
X+ #ifdef ASLD
X+ #define ESC2		.byte	0x0F	/* escape for some 286 instructions */
X+ #define defsgdt(adr)	ESC2;	add	adr,ax	/* may not be general */
X+ #define insw		.byte	0x6D
X+ #define outsw		.byte	0x6F
X+ #else
X+ #define defsgdt(adr)	sgdt	adr
X+ #endif
X+ 
X+ #ifdef i80286
X+ #ifdef ASLD
X+ #define deflgdt(adr)	ESC2;	add	adr,dx	/* may not be general */
X+ #define deflidt(adr)	ESC2;	add	adr,bx	/* may not be general */
X+ #define deflldt(adr)	ESC2;	addb	adr,dl	/* may not be general */
X+ #define defltrax	ESC2;	.byte	0x00,0xD8
X+ #define defsidt(adr)	ESC2;	add	adr,cx	/* may not be general */
X+ #define defsldt(adr)	ESC2;	addb	adr,al	/* may not be general */
X+ #define popa		.byte	0x61
X+ #define pusha		.byte	0x60
X+ #define pushi8(n)	.byte	0x6A;	.byte	n
X+ #define pushi16(n)	.byte	0x68;	.word	n
X+ #define use32
X+ #else
X+ #define deflgdt(adr)	lgdt	adr
X+ #define deflidt(adr)	lidt	adr
X+ #define deflldt(adr)	lldt	adr
X+ #define defltrax	ltr	ax
X+ #define defsidt(adr)	sidt	adr
X+ #define defsldt(adr)	sldt	adr
X+ #define pushi8(n)	push	#n
X+ #define pushi16(n)	push	#n
X+ #endif /* ASLD */
X+ #endif /* i80286 */
END_OF_FILE
if test 5266 -ne `wc -c <'kerneldif/sconst.h.cdif'`; then
    echo shar: \"'kerneldif/sconst.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/sconst.h.cdif'
fi
if test -f 'kerneldif/sglo.h.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/sglo.h.cdif'\"
else
echo shar: Extracting \"'kerneldif/sglo.h.cdif'\" \(4801 characters\)
sed "s/^X//" >'kerneldif/sglo.h.cdif' <<'END_OF_FILE'
X*** /dev/null	Thu Oct 13 22:40:42 1988
X--- kernel/sglo.h	Sun Mar 26 01:14:24 1989
X***************
X*** 0 ****
X--- 1,250 ----
X+ /* Functions, variables and data structures defined in various assembler
X+  * files. Each file should have a define like "#define KLIB88 .define" to
X+  * say what it is defining.
X+  */
X+ 
X+ 	.text
X+ 
X+ #ifndef DB286
X+ #define DB286 .extern
X+ #endif
X+ #ifndef KLIB88
X+ #define KLIB88 .extern
X+ #endif
X+ #ifndef KLIB286
X+ #define KLIB286 .extern
X+ #endif
X+ #ifndef MPX88
X+ #define MPX88 .extern
X+ #endif
X+ #ifndef MPX286
X+ #define MPX286 .extern
X+ #endif
X+ #ifndef RS2
X+ #define RS2 .extern
X+ #endif
X+ 
X+ /* Functions defined in db286.x. */
X+ 
X+ #ifdef i80286
X+ #ifdef DEBUGGER
X+ DB286		_debug2_exception
X+ DB286		_patch_phys_copy
X+ DB286		_unpatch_phys_copy
X+ #endif
X+ #endif
X+ 
X+ /* Functions defined in klib88.x. */
X+ 
X+ KLIB88		_ack_char
X+ KLIB88		_build_sig
X+ KLIB88		_check_mem
X+ KLIB88		_cim_at_wini
X+ KLIB88		_cim_printer
X+ KLIB88		_cim_xt_wini
X+ KLIB88		_cp_mess
X+ KLIB88		cret
X+ KLIB88		csv
X+ KLIB88		_exit
X+ KLIB88		.fat
X+ KLIB88		_get_phys_byte
X+ KLIB88		_get_chrome
X+ KLIB88		_get_ega
X+ KLIB88		_get_extmemsize
X+ KLIB88		_get_memsize
X+ KLIB88		_lock
X+ KLIB88		_phys_copy
X+ KLIB88		_porti_out
X+ KLIB88		_port_read
X+ KLIB88		_port_write
X+ KLIB88		_reboot
X+ KLIB88		_restore
X+ KLIB88		_save_tty_vec
X+ KLIB88		_scr_down
X+ KLIB88		_scr_up
X+ KLIB88		_sim_printer
X+ KLIB88		_tasim_printer
X+ KLIB88		_test_and_set
X+ KLIB88		.trp
X+ KLIB88		_unlock
X+ KLIB88		_vid_copy
X+ KLIB88		_wait_retrace
X+ KLIB88		_wreboot
X+ 
X+ #ifndef DEBUGGER
X+ KLIB88		_codeseg
X+ KLIB88		_dataseg
X+ KLIB88		_get_processor
X+ KLIB88		_inportb
X+ #endif
X+ 
X+ /* Functions defined in klib286.x. */
X+ 
X+ #ifdef i80286
X+ KLIB286		_klib286_init		/* this patches the rest */
X+ #endif
X+ 
X+ /* Functions defined in mpx88.x. */
X+ 
X+ MPX88		begtext
X+ MPX88		_idle_task
X+ MPX88		kernel_ds
X+ MPX88		_restart
X+ MPX88		save
X+ 
X+ MPX88		_int00			/* exception handlers */
X+ MPX88		_int01
X+ MPX88		_int02
X+ MPX88		_int03
X+ MPX88		_int04
X+ MPX88		_int05
X+ MPX88		_int06
X+ MPX88		_int07
X+ MPX88		_int08
X+ MPX88		_int09
X+ MPX88		_int10
X+ MPX88		_int11
X+ MPX88		_int12
X+ MPX88		_int13
X+ MPX88		_int14
X+ MPX88		_int15
X+ MPX88		_int16
X+ MPX88		_trp
X+ 
X+ MPX88		_clock_int		/* interrupt handlers */
X+ MPX88		_tty_int
X+ #ifdef C_RS232_INT_HANDLERS
X+ MPX88		_secondary_int
X+ MPX88		_rs232_int
X+ #ifdef i80286
X+ MPX88		_psecondary_int
X+ MPX88		_prs232_int
X+ #endif
X+ #endif
X+ MPX88		_wini_int
X+ MPX88		_disk_int
X+ MPX88		_lpr_int
X+ 
X+ MPX88		_s_call			/* trap handlers */
X+ 
X+ /* Functions defined in mpx286.x. */
X+ 
X+ #ifdef i80286
X+ MPX286		p2_errexception
X+ MPX286		p2_save
X+ MPX286		p2_resdone
X+ MPX286		p_restart
X+ 
X+ MPX286		_divide_error		/* exception handlers */
X+ MPX286		_nmi
X+ MPX286		_overflow
X+ MPX286		_bounds_check
X+ MPX286		_inval_opcode
X+ MPX286		_copr_not_available
X+ MPX286		_double_fault
X+ MPX286		_copr_seg_overrun
X+ MPX286		_inval_tss
X+ MPX286		_segment_not_present
X+ MPX286		_stack_exception
X+ MPX286		_general_protection
X+ 
X+ MPX286		_p2_s_call		/* trap handlers */
X+ #endif /* i80286 */
X+ 
X+ /* Functions defined in rs2.x. */
X+ 
X+ #ifndef C_RS232_INT_HANDLERS
X+ #ifdef i80286
X+ RS2		_prs232_int
X+ RS2		_psecondary_int
X+ RS2		rs2_iret
X+ #endif
X+ RS2		_rs232_int
X+ RS2		_secondary_int
X+ #endif
X+ 
X+ /* C functions. */
X+ 
X+ .extern		_clock_handler
X+ #ifdef DEBUGGER
X+ .extern		_db_main	/* old real mode debugger */
X+ #endif
X+ .extern		_dp8390_int
X+ .extern		_eth_stp
X+ .extern		_exception
X+ .extern		_init_8259
X+ .extern		_interrupt
X+ .extern		_keyboard
X+ .extern		_main
X+ .extern		_panic
X+ .extern		_pr_char
X+ #ifdef C_RS232_INT_HANDLERS
X+ #ifdef OLD_TTY
X+ .extern		_rs232
X+ #else
X+ .extern		_rs232_1handler
X+ .extern		_rs232_2handler
X+ #endif
X+ #endif
X+ .extern		_scan_keyboard
X+ .extern		_sys_call
X+ #ifndef OLD_TTY
X+ .extern		_tty_wakeup
X+ #endif
X+ .extern		_unhold
X+ 
X+ 		.bss
X+ 
X+ /* Variables defined in klib88.x. */
X+ 
X+ KLIB88		splimit
X+ KLIB88		_vec_table
X+ 
X+ /* Variables defined in mpx88.x. */
X+ 
X+ MPX88		begbss
X+ MPX88		begdata
X+ MPX88		k_stktop
X+ MPX88		_sizes
X+ 
X+ /* Variables defined in mpx286.x. */
X+ 
X+ #ifdef i80286
X+ MPX286		ds_ex_number
X+ MPX286		trap_errno
X+ #endif
X+ 
X+ /* C variables. */
X+ 
X+ .extern		_blank_color
X+ .extern		_boot_parameters
X+ .extern		_held_head
X+ .extern		_held_tail
X+ .extern		_k_reenter
X+ .extern		_pc_at
X+ .extern		_port_65
X+ .extern		_proc_ptr
X+ .extern		_processor
X+ .extern		_ps
X+ .extern		_scan_code
X+ .extern		_sizeof_bparam
X+ .extern		_snow
X+ #ifndef C_RS232_INT_HANDLERS
X+ .extern		_rs_lines
X+ .extern		_tty_events
X+ #endif
X+ .extern		_vid_mask
X+ .extern		_vid_port
X+ 
X+ #ifdef i80286
X+ #ifdef DEBUGGER
X+ .extern		_bits32
X+ .extern		_db_processor
X+ .extern		_db_tss
X+ .extern		_protected
X+ #endif
X+ .extern		_gdt
X+ .extern		_tss
X+ #endif
X+ 
X+ 	.text
END_OF_FILE
if test 4801 -ne `wc -c <'kerneldif/sglo.h.cdif'`; then
    echo shar: \"'kerneldif/sglo.h.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/sglo.h.cdif'
fi
if test -f 'kerneldif/xt_wini.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/xt_wini.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/xt_wini.c.cdif'\" \(4227 characters\)
sed "s/^X//" >'kerneldif/xt_wini.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/xt_wini.c	Sat Oct 15 20:17:38 1988
X--- kernel/xt_wini.c	Sun Mar 26 01:30:14 1989
X***************
X*** 247,249 ****
X  
X!   int mode, low_addr, high_addr, top_addr, low_ct, high_ct, top_end, old_state;
X    vir_bytes vir, ct;
X--- 247,249 ----
X  
X!   int mode, low_addr, high_addr, top_addr, low_ct, high_ct, top_end;
X    vir_bytes vir, ct;
X***************
X*** 273,275 ****
X    /* Now set up the DMA registers. */
X-   old_state = lock();
X    port_out(DMA_M2, mode);	/* set the DMA mode */
X--- 273,274 ----
X***************
X*** 281,283 ****
X    port_out(DMA_COUNT, high_ct);	/* output high 8 bits of count - 1 */
X-   restore(old_state);
X  }
X--- 280,281 ----
X***************
X*** 319,323 ****
X  /*===========================================================================*
X!  *				win_results					 * 
X   *===========================================================================*/
X! PRIVATE int win_results(wn)
X  register struct wini *wn;	/* pointer to the drive struct */
X--- 317,321 ----
X  /*===========================================================================*
X!  *				old_win_results					 * 
X   *===========================================================================*/
X! PRIVATE int old_win_results(wn)
X  register struct wini *wn;	/* pointer to the drive struct */
X***************
X*** 479,482 ****
X  {
X-   int old_state;
X- 
X    command[0] = WIN_SPECIFY;		/* Specify some parameters */
X--- 477,478 ----
X***************
X*** 486,488 ****
X  		return(ERR);
X- 	old_state = lock();
X  
X--- 482,483 ----
X***************
X*** 511,513 ****
X    win_out(paramp->max_ecc);
X- 	restore(old_state);
X  
X--- 506,507 ----
X***************
X*** 601,603 ****
X  	register int i;
X! 	int r, old_state;
X  
X--- 595,597 ----
X  	register int i;
X! 	int r;
X  
X***************
X*** 617,620 ****
X  
X- 	old_state = lock();
X- 
X  	for (i=0; i<6; i++) {
X--- 611,612 ----
X***************
X*** 632,635 ****
X  
X- 	restore(old_state);
X- 
X  	if(i != 6) {
X--- 624,625 ----
X***************
X*** 644,645 ****
X--- 634,636 ----
X   *===========================================================================*/
X+ 
X  PRIVATE init_params()
X***************
X*** 656,658 ****
X    /* Get the number of drives from the bios */
X!   phys_copy(0x475L, umap(proc_addr(WINCHESTER), D, buf, 1), 1L);
X    nr_drives = (int) *buf > MAX_DRIVES ? MAX_DRIVES : (int) *buf;
X--- 647,649 ----
X    /* Get the number of drives from the bios */
X!   phys_copy(0x475L, umap(cproc_addr(WINCHESTER), D, buf, 1), 1L);
X    nr_drives = (int) *buf > MAX_DRIVES ? MAX_DRIVES : (int) *buf;
X***************
X*** 731,733 ****
X    address = ((phys_bytes)segment << 4) + offset;
X!   phys_copy(address, umap(proc_addr(WINCHESTER), D, buf, 64), 64L);
X  
X--- 722,724 ----
X    address = ((phys_bytes)segment << 4) + offset;
X!   phys_copy(address, umap(cproc_addr(WINCHESTER), D, buf, 64), 64L);
X  
X***************
X*** 783,787 ****
X  /*==========================================================================*
X!  *								copy_params					 				*
X   *==========================================================================*/
X! PRIVATE copy_params(src, dest)
X  register unsigned char *src;
X--- 774,778 ----
X  /*==========================================================================*
X!  *								copy_param					 				*
X   *==========================================================================*/
X! PRIVATE copy_param(src, dest)
X  register unsigned char *src;
X***************
X*** 820,821 ****
X--- 811,813 ----
X  	wn->wn_low = *(long *)&buf[offset];
X+ #ifdef STUPID_WINI_ADJUST
X  	if ((wn->wn_low % (BLOCK_SIZE/SECTOR_SIZE)) != 0) {
X***************
X*** 825,826 ****
X--- 817,819 ----
X  	}
X+ #endif
X  	wn->wn_size = *(long *)&buf[offset + sizeof(long)] - adjust;
X***************
X*** 853 ****
X--- 846,863 ----
X  
X+ 
X+ /*==========================================================================*
X+  *				win_results				    *
X+  *==========================================================================*/
X+ PRIVATE int win_results(wn)
X+ register struct wini *wn;	/* pointer to the drive struct */
X+ {
X+ /* Extract results from the controller after an operation, then reenable the
X+  * interrupt controller.
X+  */
X+ 
X+   int r;
X+ 
X+   r = old_win_results(wn);
X+   cim_xt_wini();
X+   return(r);
X+ }
END_OF_FILE
if test 4227 -ne `wc -c <'kerneldif/xt_wini.c.cdif'`; then
    echo shar: \"'kerneldif/xt_wini.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/xt_wini.c.cdif'
fi
if test -f 'libdif/head.s.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libdif/head.s.cdif'\"
else
echo shar: Extracting \"'libdif/head.s.cdif'\" \(1162 characters\)
sed "s/^X//" >'libdif/head.s.cdif' <<'END_OF_FILE'
X*** lib-1.3/IBM_PC/head.s	Wed Nov  2 09:00:07 1988
X--- lib/IBM_PC/head.s	Thu Feb 16 02:07:37 1989
X***************
X*** 4,6 ****
X  	jmp L0
X! 	.zerow 7		| kernel uses this area as stack for inital IRET
X  L0:	mov sp,_stackpt
X--- 4,8 ----
X  	jmp L0
X! 	.zerow 13		| stack for inital IRET when common I&D
X! 				| also padding to make INIT_SP same as
X! 				| for separate I&D
X  L0:	mov sp,_stackpt
X***************
X*** 12,15 ****
X  _data_org:			| fs needs to know where build stuffed table
X! .word 0xDADA,0,0,0,0,0,0,0	| first 8 words of MM, FS, INIT are for stack
X! 				| 0xDADA is magic number for build
X  .bss
X--- 14,25 ----
X  _data_org:			| fs needs to know where build stuffed table
X! .word 0xDADA			| magic number for build
X! .word 8				| CLICK_SHIFT to check - must match h/const.h
X! .word 0,0,0			| used by FS only for sizes of init
X! 				| stack for separate I&D follows
X! .word 0,0,0			| for ip:ss:f pushed by debugger traps
X! .word 0,0,0			| for cs:ds:ret adr in save()
X! 				| this was missing - a bug as late as V1.3c
X! 				| for ds for new restart() as well
X! .word 0,0,0			| for ip:ss:f built by restart()
X! 				| so INIT_SP in const.h must be 0x1C
X  .bss
END_OF_FILE
if test 1162 -ne `wc -c <'libdif/head.s.cdif'`; then
    echo shar: \"'libdif/head.s.cdif'\" unpacked with wrong size!
fi
# end of 'libdif/head.s.cdif'
fi
if test -f 'toolsdif/fsck1.s.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toolsdif/fsck1.s.cdif'\"
else
echo shar: Extracting \"'toolsdif/fsck1.s.cdif'\" \(462 characters\)
sed "s/^X//" >'toolsdif/fsck1.s.cdif' <<'END_OF_FILE'
X*** tools-1.3/fsck1.s	Wed Nov  2 09:00:07 1988
X--- tools/fsck1.s	Wed Mar 22 05:04:23 1989
X***************
X*** 25,26 ****
X--- 33,40 ----
X  	mov	bx,ax		| put scan code for '=' in bx
X+ 	sub	ax,ax		| ax == 0 to show new boot (was scan code)
X+ 	mov	si,#_boot_parameters	| pointer to boot parameters in di:si
X+ 	mov	di,ds
X+ 	mov	cx,#10		| sizeof structure in cx
X+ 				| next 'cli' and setting up segs is redundant
X+ 				| and the segments are wrong for sep I&D
X  	cli
END_OF_FILE
if test 462 -ne `wc -c <'toolsdif/fsck1.s.cdif'`; then
    echo shar: \"'toolsdif/fsck1.s.cdif'\" unpacked with wrong size!
fi
# end of 'toolsdif/fsck1.s.cdif'
fi
echo shar: End of archive 8 \(of 10\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 9 - By Bruce Evans
Message-ID: <5271@ditmela.oz>
Date: 18 May 89 01:28:15 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 1117


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 9 (of 10)."
# Contents:  kerneldif/system.c.cdif mmdif/alloc.c.cdif
#   mmdif/main.c.cdif toolsdif/fsck.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:37 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/system.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/system.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/system.c.cdif'\" \(20205 characters\)
sed "s/^X//" >'kerneldif/system.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/system.c	Fri Oct  7 21:02:52 1988
X--- kernel/system.c	Thu Mar 23 23:13:35 1989
X***************
X*** 17,18 ****
X--- 17,21 ----
X   *   SYS_COPY	 requests a block of data to be copied between processes
X+  *   SYS_GBOOT	 copies the boot parameters to a process
X+  *   SYS_UMAP	 compute the physical address for a given virtual address
X+  *   SYS_MEM	 returns the next free chunk of physical memory 
X   *
X***************
X*** 36,37 ****
X--- 39,42 ----
X   * | SYS_ABORT  |         |         |         |         |
X+  * |------------+---------+---------+---------+---------|
X+  * | SYS_GBOOT  | proc nr |         |         | bootptr |
X   * ------------------------------------------------------
X***************
X*** 51,54 ****
X   * --------------------------------------------------------------------------
X   *
X!  * In addition to the main sys_task() entry point, there are three other minor
X   * entry points:
X--- 56,67 ----
X   * --------------------------------------------------------------------------
X+  * | SYS_UMAP   |  seg  |proc nr |vir adr|       |        |       | byte ct |
X+  * --------------------------------------------------------------------------
X   *
X!  *
X!  *    mem_type    DEVICE    PROC_NR    COUNT   POSITION
X!  * |------------+---------+---------+---------+---------|
X!  * | SYS_MEM    | extflag |         |mem size |mem base |
X!  * ------------------------------------------------------
X!  *
X!  * In addition to the main sys_task() entry point, there are 4 other minor
X   * entry points:
X***************
X*** 57,58 ****
X--- 70,72 ----
X   *   umap:	compute the physical address for a given virtual address
X+  *   alloc_segments: allocate segments for 8088 or higher processor
X   */
X***************
X*** 61,62 ****
X--- 75,77 ----
X  #include "../h/type.h"
X+ #include "../h/boot.h"
X  #include "../h/callnr.h"
X***************
X*** 69,70 ****
X--- 84,86 ----
X  #include "proc.h"
X+ #include "protect.h"
X  
X***************
X*** 72,73 ****
X--- 88,90 ----
X  
X+ extern phys_bytes check_mem();
X  extern phys_bytes umap();
X***************
X*** 100,101 ****
X--- 117,121 ----
X  	    case SYS_COPY:	r = do_copy(&m);	break;
X+ 	    case SYS_GBOOT:	r = do_gboot(&m);	break;
X+ 	    case SYS_UMAP:	r = do_umap(&m);	break;
X+ 	    case SYS_MEM:	r = do_mem(&m);		break;
X  	    default:		r = E_BAD_FCN;
X***************
X*** 113,143 ****
X  PRIVATE int do_fork(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X! /* Handle sys_fork().  'k1' has forked.  The child is 'k2'. */
X  
X    register struct proc *rpc;
X!   register char *sptr, *dptr;	/* pointers for copying proc struct */
X!   int k1;			/* number of parent process */
X!   int k2;			/* number of child process */
X!   int pid;			/* process id of child */
X!   int bytes;			/* counter for copying proc struct */
X  
X!   k1 = m_ptr->PROC1;		/* extract parent slot number from msg */
X!   k2 = m_ptr->PROC2;		/* extract child slot number */
X!   pid = m_ptr->PID;		/* extract child process id */
X  
X-   if (k1 < 0 || k1 >= NR_PROCS || k2 < 0 || k2 >= NR_PROCS)return(E_BAD_PROC);
X-   rpc = proc_addr(k2);
X- 
X    /* Copy parent 'proc' struct to child. */
X!   sptr = (char *) proc_addr(k1);	/* parent pointer */
X!   dptr = (char *) proc_addr(k2);	/* child pointer */
X!   bytes = sizeof(struct proc);		/* # bytes to copy */
X!   while (bytes--) *dptr++ = *sptr++;	/* copy parent struct to child */
X  
X    rpc->p_flags |= NO_MAP;	/* inhibit the process from running */
X!   rpc->p_flags &= ~PENDING;	/* only one in group should have PENDING */
X    rpc->p_pending = 0;
X!   rpc->p_pid = pid;		/* install child's pid */
X!   rpc->p_reg[RET_REG] = 0;	/* child sees pid = 0 to know it is child */
X  
X--- 133,166 ----
X  PRIVATE int do_fork(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X! /* Handle sys_fork().  m_ptr->PROC1 has forked.  The child is m_ptr->PROC2. */
X  
X+ #ifdef i80286
X+   u16_t old_ldt_sel;
X+ #endif
X    register struct proc *rpc;
X!   struct proc *rpp;
X  
X!   if (!isoksusern(m_ptr->PROC1) || !isoksusern(m_ptr->PROC2))
X! 	return(E_BAD_PROC);
X!   rpp = proc_addr(m_ptr->PROC1);
X!   rpc = proc_addr(m_ptr->PROC2);
X  
X    /* Copy parent 'proc' struct to child. */
X! #ifdef i80286
X!   old_ldt_sel = rpc->p_ldt_sel;	/* stop this being obliterated by copy */
X! #endif
X!   *rpc = *rpp;
X!   rpc->p_nr = m_ptr->PROC2;	/* this was obliterated by copy */
X! #ifdef i80286
X!   rpc->p_ldt_sel = old_ldt_sel;
X! #endif
X  
X    rpc->p_flags |= NO_MAP;	/* inhibit the process from running */
X!   rpc->p_flags &= ~(PENDING | SIG_PENDING);
X! 				/* only one in group should have PENDING */
X    rpc->p_pending = 0;
X!   rpc->p_pendcount = 0;
X!   rpc->p_pid = m_ptr->PID;	/* install child's pid */
X!   rpc->p_reg.r16.retreg = 0;	/* child sees pid = 0 to know it is child*/
X  
X***************
X*** 171,173 ****
X    map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
X!   if (k < -NR_TASKS || k >= NR_PROCS) return(E_BAD_PROC);
X    rp = proc_addr(k);		/* ptr to entry of user getting new map */
X--- 194,196 ----
X    map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
X!   if (!isokprocn(k)) return(E_BAD_PROC);
X    rp = proc_addr(k);		/* ptr to entry of user getting new map */
X***************
X*** 180,196 ****
X  	panic("bad call to sys_newmap (src)", NO_NUM);
X!   if ( (dst_phys = umap(proc_addr(SYSTASK), D, vsys, vn)) == 0)
X  	panic("bad call to sys_newmap (dst)", NO_NUM);
X    phys_copy(src_phys, dst_phys, pn);
X! 
X! #ifdef i8088
X!   /* On 8088, set segment registers. */
X!   rp->p_reg[CS_REG] = rp->p_map[T].mem_phys;	/* set cs */
X!   rp->p_reg[DS_REG] = rp->p_map[D].mem_phys;	/* set ds */
X!   rp->p_reg[SS_REG] = rp->p_map[D].mem_phys;	/* set ss */
X!   rp->p_reg[ES_REG] = rp->p_map[D].mem_phys;	/* set es */
X! #endif
X! 
X    old_flags = rp->p_flags;	/* save the previous value of the flags */
X    rp->p_flags &= ~NO_MAP;
X!   if (old_flags != 0 && rp->p_flags == 0) ready(rp);
X    return(OK);
X--- 203,211 ----
X  	panic("bad call to sys_newmap (src)", NO_NUM);
X!   if ( (dst_phys = umap(cproc_addr(SYSTASK), D, vsys, vn)) == 0)
X  	panic("bad call to sys_newmap (dst)", NO_NUM);
X    phys_copy(src_phys, dst_phys, pn);
X!   alloc_segments(rp);
X    old_flags = rp->p_flags;	/* save the previous value of the flags */
X    rp->p_flags &= ~NO_MAP;
X!   if (old_flags != 0 && rp->p_flags == 0) lockready(rp);
X    return(OK);
X***************
X*** 203,205 ****
X  PRIVATE int do_exec(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 218,220 ----
X  PRIVATE int do_exec(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X***************
X*** 208,222 ****
X    register struct proc *rp;
X-   int k;			/* which process */
X    int *sp;			/* new sp */
X  
X!   k = m_ptr->PROC1;		/* 'k' tells which process did EXEC */
X!   sp = (int *) m_ptr->STACK_PTR;
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X!   rp->p_sp = sp;		/* set the stack pointer */
X!   rp->p_pcpsw.pc = (int (*)()) 0;	/* reset pc */
X    rp->p_alarm = 0;		/* reset alarm timer */
X    rp->p_flags &= ~RECEIVING;	/* MM does not reply to EXEC call */
X!   if (rp->p_flags == 0) ready(rp);
X!   set_name(k, (char *)sp);	/* save command string for F1 display */
X    return(OK);
X--- 223,235 ----
X    register struct proc *rp;
X    int *sp;			/* new sp */
X  
X!   sp = (int *) m_ptr->STACK_PTR;	/* bad ptr type */
X!   if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
X!   rp = proc_addr(m_ptr->PROC1);
X!   rp->p_reg.r16.sp = (u16_t) sp;	/* set the stack pointer (bad type) */
X!   rp->p_reg.r16.pc = 0;		/* reset pc */
X    rp->p_alarm = 0;		/* reset alarm timer */
X    rp->p_flags &= ~RECEIVING;	/* MM does not reply to EXEC call */
X!   if (rp->p_flags == 0) lockready(rp);
X!   set_name(m_ptr->PROC1, (char *)sp); /* save command string for F1 display */
X    return(OK);
X***************
X*** 240,242 ****
X    proc_nr = m_ptr->PROC2;	/* slot number of exiting process */
X!   if (parent < 0 || parent >= NR_PROCS || proc_nr < 0 || proc_nr >= NR_PROCS)
X  	return(E_BAD_PROC);
X--- 253,255 ----
X    proc_nr = m_ptr->PROC2;	/* slot number of exiting process */
X!   if (!isoksusern(parent) || !isoksusern(proc_nr))
X  	return(E_BAD_PROC);
X***************
X*** 244,249 ****
X    rc = proc_addr(proc_nr);
X    rp->child_utime += rc->user_time + rc->child_utime;	/* accum child times */
X    rp->child_stime += rc->sys_time + rc->child_stime;
X    rc->p_alarm = 0;		/* turn off alarm timer */
X!   if (rc->p_flags == 0) unready(rc);
X    set_name(proc_nr, (char *) 0);	/* disable command printing for F1 */
X--- 257,264 ----
X    rc = proc_addr(proc_nr);
X+   lock();
X    rp->child_utime += rc->user_time + rc->child_utime;	/* accum child times */
X    rp->child_stime += rc->sys_time + rc->child_stime;
X+   unlock();
X    rc->p_alarm = 0;		/* turn off alarm timer */
X!   if (rc->p_flags == 0) lockunready(rc);
X    set_name(proc_nr, (char *) 0);	/* disable command printing for F1 */
X***************
X*** 256,258 ****
X  	/* Check all proc slots to see if the exiting process is queued. */
X! 	for (rp = &proc[0]; rp < &proc[NR_TASKS + NR_PROCS]; rp++) {
X  		if (rp->p_callerq == NIL_PROC) continue;
X--- 271,273 ----
X  	/* Check all proc slots to see if the exiting process is queued. */
X! 	for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
X  		if (rp->p_callerq == NIL_PROC) continue;
X***************
X*** 276,277 ****
X--- 291,294 ----
X    if (rc->p_flags & PENDING) --sig_procs;
X+   rc->p_pending = 0;
X+   rc->p_pendcount = 0;
X    rc->p_flags = P_SLOT_FREE;
X***************
X*** 285,287 ****
X  PRIVATE int do_getsp(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 302,304 ----
X  PRIVATE int do_getsp(m_ptr)
X! register message *m_ptr;		/* pointer to request message */
X  {
X***************
X*** 290,297 ****
X    register struct proc *rp;
X-   int k;				/* whose stack pointer is wanted? */
X  
X!   k = m_ptr->PROC1;
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X!   m.STACK_PTR = (char *) rp->p_sp;	/* return sp here */
X    return(OK);
X--- 307,312 ----
X    register struct proc *rp;
X  
X!   if (!isoksusern(m_ptr->PROC1)) return(E_BAD_PROC);
X!   rp = proc_addr(m_ptr->PROC1);
X!   m.STACK_PTR = (char *) rp->p_reg.r16.sp;	/* return sp here (bad t) */
X    return(OK);
X***************
X*** 304,306 ****
X  PRIVATE int do_times(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 319,321 ----
X  PRIVATE int do_times(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X***************
X*** 309,319 ****
X    register struct proc *rp;
X-   int k;
X  
X!   k = m_ptr->PROC1;		/* k tells whose times are wanted */
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X  
X    /* Insert the four times needed by the TIMES system call in the message. */
X    m_ptr->USER_TIME   = rp->user_time;
X    m_ptr->SYSTEM_TIME = rp->sys_time;
X    m_ptr->CHILD_UTIME = rp->child_utime;
X--- 324,334 ----
X    register struct proc *rp;
X  
X!   if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
X!   rp = proc_addr(m_ptr->PROC1);
X  
X    /* Insert the four times needed by the TIMES system call in the message. */
X+   lock();
X    m_ptr->USER_TIME   = rp->user_time;
X    m_ptr->SYSTEM_TIME = rp->sys_time;
X+   unlock();
X    m_ptr->CHILD_UTIME = rp->child_utime;
X***************
X*** 353,360 ****
X    proc_nr = m_ptr->PR;		/* process being signalled */
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X    sig_handler = m_ptr->FUNC;	/* run time system addr for catching sigs */
X-   if (proc_nr < LOW_USER || proc_nr >= NR_PROCS) return(E_BAD_PROC);
X-   rp = proc_addr(proc_nr);
X    vir_addr = (vir_bytes) sig_stuff;	/* info to be pushed is in 'sig_stuff' */
X!   new_sp = (vir_bytes) rp->p_sp;
X  
X--- 368,383 ----
X    proc_nr = m_ptr->PR;		/* process being signalled */
X+   if (!isokusern(proc_nr)) return(E_BAD_PROC);
X+   rp = proc_addr(proc_nr);
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X+   if (sig == -1) {
X+ 	/* Except -1 is kludged to mean "finished one KSIG". */
X+ 	if (rp->p_pendcount != 0 &&
X+ 	    --rp->p_pendcount == 0 &&
X+ 	    (rp->p_flags &= ~SIG_PENDING) == 0)
X+ 		lockready(rp);
X+ 	return;
X+   }
X    sig_handler = m_ptr->FUNC;	/* run time system addr for catching sigs */
X    vir_addr = (vir_bytes) sig_stuff;	/* info to be pushed is in 'sig_stuff' */
X!   new_sp = (vir_bytes) rp->p_reg.r16.sp;
X  
X***************
X*** 372,375 ****
X    /* Change process' sp and pc to reflect the interrupt. */
X!   rp->p_sp = (int *) new_sp;
X!   rp->p_pcpsw.pc = sig_handler;
X    return(OK);
X--- 395,398 ----
X    /* Change process' sp and pc to reflect the interrupt. */
X!   rp->p_reg.r16.sp = new_sp;
X!   rp->p_reg.r16.pc = (u16_t) sig_handler;	/* bad ptr type */
X    return(OK);
X***************
X*** 378,380 ****
X  
X! /*===========================================================================*
X   *				do_kill					     * 
X--- 401,403 ----
X  
X! /*===========================================================================
X   *				do_kill					     * 
X***************
X*** 391,393 ****
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X!   if (proc_nr < LOW_USER || proc_nr >= NR_PROCS) return(E_BAD_PROC);
X    cause_sig(proc_nr, sig);
X--- 414,416 ----
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X!   if (!isokusern(proc_nr)) return(E_BAD_PROC);
X    cause_sig(proc_nr, sig);
X***************
X*** 449,452 ****
X   * see if MM is free.  If so, a message is sent to it.  If not, when it becomes
X!  * free, a message is sent.  The calling process is blocked as long as
X!  * p_pending is non-zero.
X   */
X--- 472,478 ----
X   * see if MM is free.  If so, a message is sent to it.  If not, when it becomes
X!  * free, a message is sent.  The process being signaled is blocked while MM
X!  * has not seen or finished with all signals for it.  These signals are
X!  * counted in p_pendcount, and the SIG_PENDING flag is kept nonzero while
X!  * there are some.  It is not sufficient to ready the process when MM is
X!  * informed, because MM can block waiting for FS to do a core dump.
X   */
X***************
X*** 456,464 ****
X    rp = proc_addr(proc_nr);
X!   if ((rp->p_flags & PENDING) == 0)
X! 	sig_procs++;		/* incr if a new proc is now pending */
X!   if (rp->p_flags == 0) unready(rp);
X!   rp->p_flags |= PENDING;
X    rp->p_pending |= 1 << (sig_nr - 1);
X  
X!   mmp = proc_addr(MM_PROC_NR);
X    if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY)
X--- 482,495 ----
X    rp = proc_addr(proc_nr);
X!   if (rp->p_pending & (1 << (sig_nr - 1)))
X! 	return;			/* this signal already pending */
X    rp->p_pending |= 1 << (sig_nr - 1);
X+   ++rp->p_pendcount;		/* count new signal pending */
X+   if (rp->p_flags & PENDING)
X+ 	return;			/* another signal already pending */
X+   if (rp->p_flags == 0)
X+ 	lockunready(rp);
X+   rp->p_flags |= PENDING | SIG_PENDING;
X+   ++sig_procs;			/* count new process pending */
X  
X!   mmp = cproc_addr(MM_PROC_NR);
X    if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY)
X***************
X*** 484,496 ****
X    /* MM is waiting for new input.  Find a process with pending signals. */
X!   for (rp = proc_addr(0); rp < proc_addr(NR_PROCS); rp++)
X  	if (rp->p_flags & PENDING) {
X  		m.m_type = KSIG;
X! 		m.PROC1 = rp - proc - NR_TASKS;
X  		m.SIG_MAP = rp->p_pending;
X  		sig_procs--;
X! 		if (mini_send(HARDWARE, MM_PROC_NR, &m) != OK) 
X  			panic("can't inform MM", NO_NUM);
X  		rp->p_pending = 0;	/* the ball is now in MM's court */
X! 		rp->p_flags &= ~PENDING;
X! 		if (rp->p_flags == 0) ready(rp);
X  		return;
X--- 515,527 ----
X    /* MM is waiting for new input.  Find a process with pending signals. */
X!   for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++)
X  	if (rp->p_flags & PENDING) {
X  		m.m_type = KSIG;
X! 		m.PROC1 = proc_number(rp);
X  		m.SIG_MAP = rp->p_pending;
X  		sig_procs--;
X! 		if (lockmini_send(cproc_addr(HARDWARE), MM_PROC_NR, &m) != OK)
X  			panic("can't inform MM", NO_NUM);
X  		rp->p_pending = 0;	/* the ball is now in MM's court */
X! 		rp->p_flags &= ~PENDING;/* remains inhibited by SIG_PENDING */
X! 		lockpick_proc();	/* avoid delay in scheduling MM */
X  		return;
X***************
X*** 500,501 ****
X--- 531,534 ----
X  
X+ #ifdef i8088
X+ 
X  /*===========================================================================*
X***************
X*** 538 ****
X--- 571,689 ----
X  }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				alloc_segments				    *
X+  *==========================================================================*/
X+ PUBLIC alloc_segments(rp)
X+ register struct proc *rp;
X+ {
X+ #ifdef i80286
X+   offset_t code_bytes;
X+   offset_t data_bytes;
X+   int privilege;
X+ 
X+   if (processor >= 286) {
X+ 	data_bytes = (offset_t)(rp->p_map[S].mem_vir + rp->p_map[S].mem_len)
X+ 	             << CLICK_SHIFT;
X+ 	if (rp->p_map[T].mem_len == 0)
X+ 		code_bytes = data_bytes;	/* common I&D, poor protect */
X+ 	else
X+ 		code_bytes = (offset_t) rp->p_map[T].mem_len << CLICK_SHIFT;
X+ 	privilege = istaskp(rp) ? TASK_PRIVILEGE : USER_PRIVILEGE;
X+ 	init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
X+ 	             (offset_t) rp->p_map[T].mem_phys << CLICK_SHIFT,
X+ 	             code_bytes, privilege);
X+ 	init_dataseg(&rp->p_ldt[DS_LDT_INDEX],
X+ 	             (offset_t) rp->p_map[D].mem_phys << CLICK_SHIFT,
X+ 	             data_bytes, privilege);
X+ 	rp->p_reg.r16.cs = (CS_LDT_INDEX*DESC_SIZE) | TI | privilege;
X+ 	rp->p_reg.r16.ss =
X+ 	rp->p_reg.r16.es =
X+ 	rp->p_reg.r16.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
X+   }
X+   else
X+ #endif /* i80286 */
X+   {
X+ 	rp->p_reg.r16.cs = click_to_hclick(rp->p_map[T].mem_phys);
X+ 	rp->p_reg.r16.ss =
X+ 	rp->p_reg.r16.es =
X+ 	rp->p_reg.r16.ds = click_to_hclick(rp->p_map[D].mem_phys);
X+   }
X+ }
X+ #endif /* i8088 */
X+ 
X+ 
X+ /*==========================================================================*
X+  *				do_gboot				    *
X+  *==========================================================================*/
X+ PUBLIC struct bparam_s boot_parameters =  /* overwritten if new boot */
X+ {
X+   DROOTDEV, DRAMIMAGEDEV, DRAMSIZE, DSCANCODE, DPROCESSOR,
X+ };
X+ 
X+ PUBLIC unsigned sizeof_bparam = sizeof boot_parameters;	/* for asm to see */
X+ 
X+ PRIVATE int do_gboot(m_ptr)
X+ message *m_ptr;			/* pointer to request message */
X+ {
X+ /* Copy the boot parameters.  Normally only called during fs init. */
X+ 
X+   phys_bytes src_phys, dst_phys;
X+ 
X+   src_phys = umap(cproc_addr(SYSTASK), D, (vir_bytes) &boot_parameters,
X+                   (vir_bytes) sizeof boot_parameters);
X+   if ( (dst_phys = umap(proc_addr(m_ptr->PROC1), D,
X+                         (vir_bytes) m_ptr->MEM_PTR,
X+ 			(vir_bytes) sizeof boot_parameters)) == 0)
X+ 	panic("bad call to SYS_GBOOT", NO_NUM);
X+   phys_copy(src_phys, dst_phys, (phys_bytes) sizeof boot_parameters);
X+   return(OK);
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				do_umap					    *
X+  *==========================================================================*/
X+ PRIVATE int do_umap(m_ptr)
X+ register message *m_ptr;		/* pointer to request message */
X+ {
X+ /* Same as umap(), for non-kernel processes. */
X+ 
X+   m_ptr->SRC_BUFFER = umap(proc_addr((int) m_ptr->SRC_PROC_NR),
X+                            (int) m_ptr->SRC_SPACE,
X+                            (vir_bytes) m_ptr->SRC_BUFFER,
X+                            (vir_bytes) m_ptr->COPY_BYTES);
X+   return(OK);
X+ }
X+ 
X+ 
X+ #ifdef i8088
X+ /*===========================================================================*
X+  *				do_mem					     *
X+  *===========================================================================*/
X+ PRIVATE int do_mem(m_ptr)
X+ register message *m_ptr;		/* pointer to request message */
X+ {
X+ /* Return the base and size of the next chunk of memory of a given type. */
X+ 
X+   unsigned mem;
X+ 
X+   for (mem = 0; mem < NR_MEMS; ++mem) {
X+ 	if (memtype[mem] & 0x80) {
X+ 	    memsize[mem] = check_mem((phys_bytes) membase[mem] << CLICK_SHIFT,
X+ 	                             (phys_bytes) memsize[mem] << CLICK_SHIFT)
X+ 	                   >> CLICK_SHIFT;
X+ 	    memtype[mem] &= ~0x80;
X+ 	}
X+ 	if (memsize[mem] != 0 && m_ptr->DEVICE == memtype[mem]) {
X+ 		m_ptr->COUNT = memsize[mem];
X+ 		m_ptr->POSITION = membase[mem];
X+ 		memsize[mem] = 0;	/* now MM has it */
X+ 		return(OK);
X+ 	}
X+   }
X+   m_ptr->COUNT = 0;		/* no more */
X+   m_ptr->POSITION = 0;
X+   return(OK);
X+ }
X+ #endif /* i8088 */
END_OF_FILE
if test 20205 -ne `wc -c <'kerneldif/system.c.cdif'`; then
    echo shar: \"'kerneldif/system.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/system.c.cdif'
fi
if test -f 'mmdif/alloc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/alloc.c.cdif'\"
else
echo shar: Extracting \"'mmdif/alloc.c.cdif'\" \(3094 characters\)
sed "s/^X//" >'mmdif/alloc.c.cdif' <<'END_OF_FILE'
X*** mm-1.3/alloc.c	Wed Aug  3 21:18:01 1988
X--- mm/alloc.c	Fri Jan 13 08:55:47 1989
X***************
X*** 15,16 ****
X--- 15,17 ----
X   *   max_hole:	returns the largest hole currently available
X+  *   mem_left:	returns the sum of the sizes of all current holes
X   */
X***************
X*** 34,35 ****
X--- 35,38 ----
X  
X+ extern phys_clicks get_mem();
X+ 
X  /*===========================================================================*
X***************
X*** 201,204 ****
X   *===========================================================================*/
X! PUBLIC mem_init(clicks)
X! phys_clicks clicks;		/* amount of memory available */
X  {
X--- 204,206 ----
X   *===========================================================================*/
X! PUBLIC mem_init()
X  {
X***************
X*** 207,213 ****
X   * a linked list of table entries that are not in use.  Initially, the former
X!  * list has one entry, a single hole encompassing all of memory, and the second
X!  * list links together all the remaining table slots.  As memory becomes more
X!  * fragmented in the course of time (i.e., the initial big hole breaks up into
X!  * many small holes), new table slots are needed to represent them.  These
X!  * slots are taken from the list headed by 'free_slots'.
X   */
X--- 209,215 ----
X   * a linked list of table entries that are not in use.  Initially, the former
X!  * list has one entry for each chunk of physical memory, and the second
X!  * list links together the remaining table slots.  As memory becomes more
X!  * fragmented in the course of time (i.e., the initial big holes break up into
X!  * smaller holes), new table slots are needed to represent them.  These slots
X!  * are taken from the list headed by 'free_slots'.
X   */
X***************
X*** 215,224 ****
X    register struct hole *hp;
X  
X    for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
X-   hole[0].h_next = NIL_HOLE;	/* only 1 big hole initially */
X    hole[NR_HOLES-1].h_next = NIL_HOLE;
X!   hole_head = &hole[0];
X!   free_slots = &hole[1];
X!   hole[0].h_base = 0;
X!   hole[0].h_len = clicks;
X  }
X--- 217,248 ----
X    register struct hole *hp;
X+   phys_clicks base;		/* base address of chunk */
X+   phys_clicks size;		/* size of chunk */
X  
X+   /* Put all holes on the free list. */
X    for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
X    hole[NR_HOLES-1].h_next = NIL_HOLE;
X!   hole_head = NIL_HOLE;
X!   free_slots = &hole[0];
X! 
X!   /* Allocate a hole for each chunk of physical memory. */
X!   while ( (size = get_mem(&base, FALSE)) != 0)
X! 	free_mem(base, size);
X! }
X! 
X! 
X! /*===========================================================================*
X!  *				mem_left				     *
X!  *===========================================================================*/
X! PUBLIC phys_clicks mem_left()
X! {
X! /* Determine how much memory is left.  This procedure is called just after
X!  * initialization to find the original amount.
X!  */
X! 
X!   register struct hole *hp;
X!   phys_clicks tot;
X! 
X!   for (hp = hole_head, tot = 0; hp != NIL_HOLE; hp = hp->h_next)
X! 	tot += hp->h_len;
X!   return(tot);
X  }
END_OF_FILE
if test 3094 -ne `wc -c <'mmdif/alloc.c.cdif'`; then
    echo shar: \"'mmdif/alloc.c.cdif'\" unpacked with wrong size!
fi
# end of 'mmdif/alloc.c.cdif'
fi
if test -f 'mmdif/main.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/main.c.cdif'\"
else
echo shar: Extracting \"'mmdif/main.c.cdif'\" \(5879 characters\)
sed "s/^X//" >'mmdif/main.c.cdif' <<'END_OF_FILE'
X*** mm-1.3/main.c	Wed Aug  3 21:18:03 1988
X--- mm/main.c	Sat Jan 28 10:48:48 1989
X***************
X*** 25,32 ****
X  
X- #define ENOUGH (phys_clicks) 4096	/* any # > max(FS size, INIT size) */
X- #define CLICK_TO_K (1024L/CLICK_SIZE)	/* convert clicks to K */
X- 
X- PRIVATE phys_clicks tot_mem;
X  extern (*call_vec[])();
X  
X  /*===========================================================================*
X--- 25,32 ----
X  
X  extern (*call_vec[])();
X+ extern phys_clicks alloc_mem();
X+ extern phys_clicks mem_left();
X  
X+ FORWARD phys_clicks get_mem();
X+ 
X  /*===========================================================================*
X***************
X*** 110,119 ****
X  
X!   extern phys_clicks get_tot_mem(), alloc_mem();
X  
X-   /* Find out how much memory the machine has and set up core map.  MM and FS
X-    * are part of the map.  Tell the kernel.
X-    */
X-   tot_mem = get_tot_mem();	/* # clicks in mem starting at absolute 0 */
X-   mem_init(tot_mem);		/* initialize tables to all physical mem */
X- 
X    /* Initialize MM's tables. */
X--- 110,113 ----
X  
X!   mem_init();			/* initialize tables to all physical mem */
X  
X    /* Initialize MM's tables. */
X***************
X*** 123,126 ****
X    procs_in_use = 3;
X- 
X-   /* Set stack limit, which is checked on every procedure call. */
X  }
X--- 117,118 ----
X***************
X*** 146,147 ****
X--- 138,140 ----
X    phys_clicks init_text_clicks, init_data_clicks;
X+   phys_clicks minix_clicks;
X  
X***************
X*** 149,164 ****
X  
X!   /* Remove the memory used by MINIX and RAM disk from the memory map. */
X    init_text_clicks = mm_in.m1_i1;	/* size of INIT in clicks */
X    init_data_clicks = mm_in.m1_i2;	/* size of INIT in clicks */
X-   tot_clicks = mm_in.m1_i3;		/* total size of MINIX + RAM disk */
X    init_org = (phys_clicks) mm_in.m1_p1;	/* addr where INIT begins in memory */
X    init_clicks = init_text_clicks + init_data_clicks;
X!   ram_base = init_org + init_clicks;	/* start of RAM disk */
X!   ram_clicks = tot_clicks - ram_base;	/* size of RAM disk */
X!   alloc_mem(tot_clicks);		/* remove RAM disk from map */
X  
X    /* Print memory information. */
X!   mem1 = tot_mem/CLICK_TO_K;
X!   mem2 = (ram_base + 512/CLICK_SIZE)/CLICK_TO_K;	/* MINIX, rounded */
X!   mem3 = ram_clicks/CLICK_TO_K;
X  #ifndef ATARI_ST
X--- 142,171 ----
X  
X!   /* Remove the memory used by MINIX from the memory map. */
X    init_text_clicks = mm_in.m1_i1;	/* size of INIT in clicks */
X    init_data_clicks = mm_in.m1_i2;	/* size of INIT in clicks */
X    init_org = (phys_clicks) mm_in.m1_p1;	/* addr where INIT begins in memory */
X    init_clicks = init_text_clicks + init_data_clicks;
X!   minix_clicks = init_org + init_clicks;	/* size of system in clicks */
X!   ram_base = alloc_mem(minix_clicks);	/* remove MINIX from map */
X!   if (ram_base != 0)
X! 	panic("inconsistent system memory base", ram_base);
X  
X+   /* Remove the memory used by the RAM disk from the memory map. */
X+   tot_clicks = mm_in.m1_i3;		/* total size of MINIX + RAM disk */
X+   ram_clicks = tot_clicks - minix_clicks;	/* size of RAM disk */
X+ #ifdef i8088
X+   /* Put RAM disk in extended memory, if any. */
X+   if (get_mem(&ram_base, TRUE) >= ram_clicks)
X+ 	goto got_base;
X+ #endif
X+   ram_base = alloc_mem(ram_clicks);	/* remove the RAM disk from the map */
X+   if (ram_base == NO_MEM)
X+ 	panic("not enough memory for RAM disk", NO_NUM);
X+ got_base:
X+   mm_out.POSITION = (phys_bytes) ram_base * CLICK_SIZE;	/* tell FS where */
X+ 
X    /* Print memory information. */
X!   mem1 = click_to_round_k(minix_clicks + ram_clicks + mem_left());  
X!   mem2 = click_to_round_k(minix_clicks);
X!   mem3 = click_to_round_k(ram_clicks);
X  #ifndef ATARI_ST
X***************
X*** 195,198 ****
X  #ifdef ATARI_ST
X  /*===========================================================================*
X!  *				get_tot_mem				     *
X   *===========================================================================*/
X--- 202,210 ----
X  #ifdef ATARI_ST
X+ /* This should be moved to the kernel, like the PC version.  It has already
X+  * been modified to match the other changes, but won't compile as is since
X+  * there this file also contains the preferred version of get_mem() (which
X+  * doesn't deserve #ifdef i8088).
X+  */
X  /*===========================================================================*
X!  *				get_mem					     *
X   *===========================================================================*/
X***************
X*** 202,207 ****
X   */
X! PUBLIC phys_clicks get_tot_mem()
X  {
X    long i;
X  
X    if (mem_copy(
X--- 214,225 ----
X   */
X! PRIVATE phys_clicks get_mem(pbase, extflag)
X! phys_clicks *pbase;		/* where to return the base */
X! int extflag;			/* nonzero for extended memory */
X  {
X    long i;
X+   static unsigned already;
X  
X+   *pbase = 0;
X+   if (already) return(0);	/* only one chunk */
X+   already = TRUE;
X    if (mem_copy(
X***************
X*** 215 ****
X--- 233,255 ----
X  #endif
X+ 
X+ 
X+ /*===========================================================================*
X+  *				get_mem					     *
X+  *===========================================================================*/
X+ PUBLIC phys_clicks get_mem(pbase, extflag)
X+ phys_clicks *pbase;		/* where to return the base */
X+ int extflag;			/* nonzero for extended memory */
X+ {
X+ /* Ask kernel for the next chunk of memory.  'extflag' specifies the type of
X+  * memory.  "Extended" memory here means memory above 1MB which is no good
X+  * for putting programs in but usable for the RAM disk.  MM doesn't care
X+  * about the locations of the 2 types of memory, except memory above 1MB is
X+  * unreachable unless CLICK_SIZE > 16, but still usable for the RAM disk.
X+  */
X+   mm_out.m_type = SYS_MEM;
X+   mm_out.DEVICE = extflag;
X+   if (sendrec(SYSTASK, &mm_out) != OK || mm_out.m_type != OK)
X+ 	panic("Kernel didn't respond to get_mem", NO_NUM);
X+   *pbase = (phys_clicks) mm_out.POSITION;
X+   return((phys_clicks) mm_out.COUNT);
X+ }
END_OF_FILE
if test 5879 -ne `wc -c <'mmdif/main.c.cdif'`; then
    echo shar: \"'mmdif/main.c.cdif'\" unpacked with wrong size!
fi
# end of 'mmdif/main.c.cdif'
fi
if test -f 'toolsdif/fsck.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toolsdif/fsck.c.cdif'\"
else
echo shar: Extracting \"'toolsdif/fsck.c.cdif'\" \(5747 characters\)
sed "s/^X//" >'toolsdif/fsck.c.cdif' <<'END_OF_FILE'
X*** tools-1.3/fsck.c	Thu Oct  6 23:01:16 1988
X--- tools/fsck.c	Fri Mar  3 00:41:29 1989
X***************
X*** 45,46 ****
X--- 45,53 ----
X  
X+ #ifdef STANDALONE
X+ #  include "../h/boot.h"
X+ struct bparam_s boot_parameters =
X+   { DROOTDEV, DRAMIMAGEDEV, DRAMSIZE, DSCANCODE, DPROCESSOR };
X+ char *ramimname = "/dev/fd0";
X+ char *rootname = "/dev/ram";
X+ #endif
X  
X***************
X*** 53,56 ****
X  
X! #define quote(x)	x
X! #define nextarg(t)	(*argp.quote(u_)t++)
X  
X--- 60,62 ----
X  
X! #define nextarg(t)	(*argp.t++)
X  
X***************
X*** 289,303 ****
X  			case 'c':
X! 			case 'C':  prc(nextarg(char));		break;
X! 			case 'b':  prn(unsigned,  2, 0);	break;
X! 			case 'B':  prn(long,      2, 0);	break;
X! 			case 'o':  prn(unsigned,  8, 0);	break;
X! 			case 'O':  prn(long,      8, 0);	break;
X! 			case 'd':  prn(int,      10, 1);	break;
X! 			case 'D':  prn(long,     10, 1);	break;
X! 			case 'u':  prn(unsigned, 10, 0);	break;
X! 			case 'U':  prn(long,     10, 0);	break;
X! 			case 'x':  prn(unsigned, 16, 0);	break;
X! 			case 'X':  prn(long,     16, 0);	break;
X  			case 's':
X! 			case 'S':  s = nextarg(charp);
X  				   while (*s) prc(*s++);	break;
X--- 295,309 ----
X  			case 'c':
X! 			case 'C':  prc(nextarg(u_char));	break;
X! 			case 'b':  prn(u_unsigned,  2, 0);	break;
X! 			case 'B':  prn(u_long,      2, 0);	break;
X! 			case 'o':  prn(u_unsigned,  8, 0);	break;
X! 			case 'O':  prn(u_long,      8, 0);	break;
X! 			case 'd':  prn(u_int,      10, 1);	break;
X! 			case 'D':  prn(u_long,     10, 1);	break;
X! 			case 'u':  prn(u_unsigned, 10, 0);	break;
X! 			case 'U':  prn(u_long,     10, 0);	break;
X! 			case 'x':  prn(u_unsigned, 16, 0);	break;
X! 			case 'X':  prn(u_long,     16, 0);	break;
X  			case 's':
X! 			case 'S':  s = nextarg(u_charp);
X  				   while (*s) prc(*s++);	break;
X***************
X*** 1817,1821 ****
X  		printf("\nHit key as follows:\n\n");
X! 		printf("    =  start MINIX (root file system in drive 0)\n");
X! 		printf("    u  start MINIX on PS/2 Model 30, U.S. keyboard (root file sys in drive 0)\n");
X! 		printf("    d  start MINIX on PS/2 Model 30, Dutch keyboard (root file sys in drive 0)\n");
X  		printf("    f  check the file system (first insert any file system diskette)\n");
X--- 1823,1838 ----
X  		printf("\nHit key as follows:\n\n");
X! 		printf("    =  start MINIX, standard keyboard\n");
X! 		printf("    u  start MINIX, U.S. keyboard\n");
X! 		printf("    d  start MINIX, Dutch keyboard\n\n");
X! 		printf("    r  select root device (now %s)\n", rootname);
X! 		printf("    i  select RAM image device (now %s)%s\n",
X! 		       ramimname,
X! 		       boot_parameters.bp_rootdev == DEV_RAM ?
X! 		       "" : " (not used - root is not RAM disk)");
X! 		printf("    s  set RAM disk size (now %u)%s\n",
X! 		       boot_parameters.bp_ramsize,
X! 		       boot_parameters.bp_rootdev == DEV_RAM ?
X! 		       " (real size is from RAM image)" : "");
X! 		printf("    p  set limit on processor type (now %u)\n\n",
X! 		       boot_parameters.bp_processor);
X  		printf("    f  check the file system (first insert any file system diskette)\n");
X***************
X*** 1868,1872 ****
X  			
X! 		case '=': return((c >> 8) & 0xFF);
X! 		case 'u': return((c >> 8) & 0xFF);
X! 		case 'd': return((c >> 8) & 0xFF);
X  		default:
X--- 1885,1913 ----
X  			
X! 		case '=':
X! 		case 'u':
X! 		case 'd':
X! 			return(boot_parameters.bp_scancode = (c >> 8) & 0xFF);
X! 
X! 		case 'i':
X! 			boot_parameters.bp_ramimagedev =
X! 			get_device(&ramimname, "ram image", 0);
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 'p':
X! 			boot_parameters.bp_processor = get_processor();
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 'r':
X! 			boot_parameters.bp_rootdev =
X! 			get_device(&rootname, "root", 1);
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 's':
X! 			boot_parameters.bp_ramsize = get_ramsize();
X! 			printf("\n\n");
X! 			continue;
X! 
X  		default:
X***************
X*** 1984,1985 ****
X--- 2025,2122 ----
X  }
X+ 
X+ #ifdef STANDALONE
X+ 
X+ int get_device(pname, description, ram_allowed)
X+ char **pname;
X+ char *description;
X+ int ram_allowed;
X+ {
X+   char chr;
X+   static char *devname[] = {
X+ 	"/dev/fd0",
X+ 	"/dev/fd1",
X+ 	"/dev/hd1",
X+ 	"/dev/hd2",
X+ 	"/dev/hd3",
X+ 	"/dev/hd4",
X+ 	"",
X+ 	"/dev/hd6",
X+ 	"/dev/hd7",
X+ 	"/dev/hd8",
X+ 	"/dev/hd9",
X+   };
X+   printf("\nPlease enter (abbreviated) name of %s device.\n", description);
X+   printf("Floppy f0, f1, hard h1 to h4, h6 to h9");
X+   if (ram_allowed)
X+ 	printf (", RAM r");
X+   printf(".\nThen hit RETURN: ");
X+   while (1) {
X+ 	switch(chr = getc()) {
X+ 	case 'f':
X+ 		putc(chr);
X+ 		while ((chr = getc()) < '0' || chr > '1')
X+ 			;
X+ 		putc(chr);
X+ 		getnewline();
X+ 		*pname = devname[chr - '0'];
X+ 		return DEV_FD0 + chr - '0';
X+ 	case 'h':
X+ 		putc(chr);
X+ 		while (((chr = getc()) < '1' || chr > '4') &&
X+ 				  (chr < '6' || chr > '9'))
X+ 			;
X+ 		putc(chr);
X+ 		getnewline();
X+ 		*pname = devname[chr +  1 - '0'];
X+ 		return DEV_HD0 + chr - '0';
X+ 	case 'r':
X+ 		if (ram_allowed) {
X+ 			putc(chr);
X+ 			getnewline();
X+ 			*pname = "/dev/ram";
X+ 			return DEV_RAM;
X+ 		}
X+ 	}
X+   }
X+ }
X+ 
X+ getnewline()
X+ {
X+ 	while ((char) getc() != '\r')
X+ 		;
X+ 	putc('\n');
X+ }
X+ 
X+ int get_processor()
X+ {
X+   printf("\nPlease enter limit on processor type. Then hit RETURN: ");
X+   return get_size();
X+ }
X+ 
X+ int get_ramsize()
X+ {
X+   printf("\nPlease enter size of RAM disk. Then hit RETURN: ");
X+   return get_size();
X+ }
X+ 
X+ int get_size()
X+ {
X+   char chr;
X+   long size;
X+ 
X+   while ((chr = getc()) < '0' || chr > '9')
X+ 	;
X+   size = chr - '0';
X+   putc(chr);
X+   while ((chr = getc()) != '\r') {
X+ 	if (chr >= '0' && chr <= '9' && 10 * size + (chr - '0') < 0x10000) {
X+ 		putc(chr);
X+ 		size = 10 * size + (chr - '0');
X+ 	}
X+   }
X+   putc('\n');
X+   return size;
X+ }
X+ 
X+ #endif /* STANDALONE */
X  
END_OF_FILE
if test 5747 -ne `wc -c <'toolsdif/fsck.c.cdif'`; then
    echo shar: \"'toolsdif/fsck.c.cdif'\" unpacked with wrong size!
fi
# end of 'toolsdif/fsck.c.cdif'
fi
echo shar: End of archive 9 \(of 10\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!lll-winken!uunet!munnari!murtoa.cs.mu.oz.au!ditmela!worsley
From: wors...@ditmela.oz (Andrew Worsley)
Newsgroups: comp.os.minix
Subject: Protected mode MINIX for 80286 Part 10 (last) - By Bruce Evans
Message-ID: <5272@ditmela.oz>
Date: 18 May 89 01:29:56 GMT
Organization: CSIRO Division of Information Technology, Australia
Lines: 490


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 10 (of 10)."
# Contents:  toolsdif/build.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:43 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'toolsdif/build.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toolsdif/build.c.cdif'\"
else
echo shar: Extracting \"'toolsdif/build.c.cdif'\" \(16217 characters\)
sed "s/^X//" >'toolsdif/build.c.cdif' <<'END_OF_FILE'
X*** tools-1.3/build.c	Tue Nov 22 03:39:10 1988
X--- tools/build.c	Wed Mar 22 04:55:54 1989
X***************
X*** 13,17 ****
X   * begins directly after it.  The kernel, mm, fs, init, and fsck are each
X!  * padded out to a multiple of 16 bytes, and then concatenated into a
X   * single file beginning 512 bytes into the file.  The first byte of sector 1
X   * contains executable code for the kernel.  There is no header present.
X   *
X--- 13,19 ----
X   * begins directly after it.  The kernel, mm, fs, init, and fsck are each
X!  * padded out to a multiple of clicksize bytes, and then concatenated into a
X   * single file beginning 512 bytes into the file.  The first byte of sector 1
X   * contains executable code for the kernel.  There is no header present.
X+  * Clicksize is the CLICK_SIZE which the kernel, mm and fs files were
X+  * compiled with, and is encoded in bytes 2-3 of the kernel code segment.
X   *
X***************
X*** 43,45 ****
X--- 45,59 ----
X  
X+ /* Modified by Bruce Evans, 21 Nov 88 to load symbol tables for debugger.
X+    For each piece of the kernel, the symbol table is loaded at the end of
X+    the bss. A pointer to it is placed in the spare word at location 2 in
X+    the code segment. The sizes array is adjusted so that the symbol table
X+    is effectively part of the data segment.
X+    It would be better for everything to load the exec headers and chain
X+    them together.
X  
X+    BDE 8 Feb 89. CLICK_SIZE 256 instead of 16.
X+    BDE 2 Mar 89. CLICK_SIZE and CLICK_SHIFT variables clicksize, click_shift.
X+  */
X+ 
X+ 
X  #define PROGRAMS 5              /* kernel + mm + fs + init + fsck = 5 */
X***************
X*** 47,48 ****
X--- 61,63 ----
X  #define DS_OFFSET 4L            /* position of DS written in kernel text seg */
X+ #define SYM_OFFSET 2L		/* position of syms writ in kernel text seg */
X  #define SECTOR_SIZE 512         /* size of buf */
X***************
X*** 51,53 ****
X  #define FS_D_MAGIC 0xDADA	/* identifies fs data space */
X! #define CLICK_SHIFT 4
X  #define KERN 0
X--- 66,69 ----
X  #define FS_D_MAGIC 0xDADA	/* identifies fs data space */
X! #define DATA_ALIGNMENT 16	/* minimum alignment of separate I&D data */
X! #define HCLICK_SHIFT 4
X  #define KERN 0
X***************
X*** 66,67 ****
X--- 82,84 ----
X  #define BSS_POS 2               /* where is bss size in header */
X+ #define SYM_POS 5               /* where is sym size in header */
X  #define SEP_ID_BIT 0x20         /* bit that tells if file is separate I & D */
X***************
X*** 83,84 ****
X--- 100,105 ----
X  
X+ unsigned click_shift;		/* CLICK_SHIFT used to compile kernel/mm/fs */
X+ unsigned clicksize;		/* CLICK_SIZE used to compile kernel/mm/fs */
X+ 				/* grrr, click_size would be ambiguous */
X+ 
X  struct sizes {
X***************
X*** 87,88 ****
X--- 108,110 ----
X    unsigned bss_size;            /* size in bytes */
X+   unsigned sym_size;            /* size in bytes */
X    int sep_id;                   /* 1 if separate, 0 if not */
X***************
X*** 156,163 ****
X  /* Open and read a file, copying it to output.  First read the header,
X!  * to get the text, data, and bss sizes.  Also see if it is separate I & D.
X!  * write the text, data, and bss to output.  The sum of these three pieces
X!  * must be padded upwards to a multiple of 16, if need be.  The individual
X!  * pieces need not be multiples of 16 bytes, except for the text size when
X!  * separate I & D is in use.  The total size must be less than 64K, even
X!  * when separate I & D space is used.
X   */
X--- 178,184 ----
X  /* Open and read a file, copying it to output.  First read the header,
X!  * to get the text, data, bss and symbol sizes.  Also see if it is separate
X!  * I & D.  Write the text, data, bss and symbols to output.  The sum of these
X!  * four pieces must be padded upwards to a multiple of clicksize, if need
X!  * be.  The individual pieces need not be multiples of clicksize bytes,
X!  * except for the text size when separate I & D is in use.
X   */
X***************
X*** 166,170 ****
X    unsigned text_bytes, data_bytes, bss_bytes, rest, filler;
X    long tot_bytes;
X-   unsigned left_to_read;
X-   char inbuf[READ_UNIT];
X    
X--- 187,190 ----
X    unsigned text_bytes, data_bytes, bss_bytes, rest, filler;
X+   unsigned file_text_bytes, sym_bytes;
X    long tot_bytes;
X    
X***************
X*** 173,178 ****
X    /* Read the header to see how big the segments are. */
X!   read_header(fd, &sepid, &text_bytes, &data_bytes, &bss_bytes, file_name);
X  
X!   /* Pad the total size to a 16-byte multiple, if needed. */
X!   if (sepid && ((text_bytes % 16) != 0) ) {
X          pexit("separate I & D but text size not multiple of 16 bytes.  File: ", 
X--- 193,216 ----
X    /* Read the header to see how big the segments are. */
X!   read_header(fd, &sepid, &text_bytes, &data_bytes, &bss_bytes, &sym_bytes,
X!               file_name);
X  
X!   /* If the kernel, determine click_shift and clicksize. */
X!   if (num == 0) {
X! 	long lseek();
X! 	unsigned char click_buf[4];
X! 
X! 	if (read(fd, click_buf, sizeof click_buf) != sizeof click_buf)
X! 		pexit("can't read click_shift in ", file_name);
X! 	if (lseek(fd, (long) -sizeof click_buf, 1) < 0)
X! 		pexit("can't seek before click_shift in ", file_name);
X! 	click_shift = click_buf[2] + (click_buf[3] << 8);
X! 	if (click_shift == 0)
X! 		click_shift = HCLICK_SHIFT;	/* old kernel */
X! 	else if (click_shift < HCLICK_SHIFT)
X! 		pexit("kernel click_shift must be >= 4", "");
X! 	clicksize = 1 << click_shift;
X!   }
X! 
X!   /* Pad the total size to a clicksize-byte multiple, if needed. */
X!   if (sepid && ((text_bytes % DATA_ALIGNMENT) != 0) ) {
X          pexit("separate I & D but text size not multiple of 16 bytes.  File: ", 
X***************
X*** 180,184 ****
X    }
X!   tot_bytes = (long)text_bytes + data_bytes + bss_bytes;
X!   rest = tot_bytes % 16;
X!   filler = (rest > 0 ? 16 - rest : 0);
X    bss_bytes += filler;
X--- 218,225 ----
X    }
X!   file_text_bytes = text_bytes;
X!   if (sepid)
X! 	text_bytes = (text_bytes + clicksize - 1) & ~(clicksize - 1);
X!   tot_bytes = (long) text_bytes + (data_bytes + bss_bytes) + sym_bytes;
X!   rest = tot_bytes % clicksize;
X!   filler = (rest > 0 ? clicksize - rest : 0);
X    bss_bytes += filler;
X***************
X*** 192,193 ****
X--- 233,235 ----
X    sizes[num].bss_size  = bss_bytes;
X+   sizes[num].sym_size  = sym_bytes;
X    sizes[num].sep_id    = sepid;
X***************
X*** 203,213 ****
X    /* Read in the text and data segments, and copy them to output. */
X!   left_to_read = text_bytes + data_bytes;
X!   while (left_to_read > 0) {
X!         count = (left_to_read < READ_UNIT ? left_to_read : READ_UNIT);
X!         bytes_read = read(fd, inbuf, count);
X!         if (bytes_read < 0) pexit("read error on file ", file_name);
X!         if (bytes_read > 0) wr_out(inbuf, bytes_read);
X!         left_to_read -= count;
X!   }
X  
X    /* Write the bss to output. */
X--- 245,257 ----
X    /* Read in the text and data segments, and copy them to output. */
X!   copy3(fd, file_text_bytes, file_name);
X  
X+   /* Oops, pad the text segment in the middle of this. */
X+   text_bytes -= file_text_bytes;	/* remainder now */
X+   while (text_bytes != 0) {
X+         count = (text_bytes < SECTOR_SIZE ? text_bytes : SECTOR_SIZE);
X+         wr_out(zero, count);
X+         text_bytes -= count;
X+   }
X+   copy3(fd, data_bytes, file_name);
X+ 
X    /* Write the bss to output. */
X***************
X*** 218,219 ****
X--- 262,267 ----
X    }
X+ 
X+   /* Copy symbol table to output. */
X+   copy3(fd, sym_bytes, file_name);
X+ 
X    close(fd);
X***************
X*** 222,228 ****
X  
X! read_header(fd, sepid, text_bytes, data_bytes, bss_bytes, file_name)
X! int fd, *sepid;
X! unsigned *text_bytes, *data_bytes, *bss_bytes;
X  char *file_name;
X  {
X  /* Read the header and check the magic number.  The standard Monix header 
X--- 270,301 ----
X  
X! copy3(fd, left_to_read, file_name)
X! int fd;
X! unsigned left_to_read;
X  char *file_name;
X  {
X+   int bytes_read;
X+   int count;
X+   char inbuf[READ_UNIT];
X+ 
X+   while (left_to_read != 0)
X+   {
X+     if ( (unsigned) (count = left_to_read) > READ_UNIT)
X+       count = READ_UNIT;
X+     if ( (bytes_read = read(fd, inbuf, count)) <= 0)
X+       pexit("read error on file ", file_name);
X+     wr_out(inbuf, bytes_read);
X+     left_to_read -= count;
X+   }
X+ }
X+ 
X+ 
X+ #ifdef XENIX_HEADER
X+ # include </usr/include/sys/a.out.h>
X+ #endif
X+ 
X+ read_header(fd, sepid, text_bytes, data_bytes, bss_bytes, sym_bytes,file_name)
X+ int fd, *sepid;
X+ unsigned *text_bytes, *data_bytes, *bss_bytes, *sym_bytes;
X+ char *file_name;
X+ {
X  /* Read the header and check the magic number.  The standard Monix header 
X***************
X*** 243,248 ****
X--- 316,349 ----
X  
X+ #ifdef XENIX_HEADER
X+   struct  aexec a_header;
X+ #else
X    long head[12];
X    unsigned short hd[4];
X+ #endif
X    int n, header_len;
X  
X+ #ifdef XENIX_HEADER
X+   /*
X+     Do it right, read header *structure* to get header length.
X+     Fortunately header has no longs so we don't have to worry about
X+     swapped words, not to mention swapped bytes.
X+   */
X+   if ((n = read(fd, &a_header, sizeof a_header)) != sizeof a_header)
X+   {
X+     printf("expected %d, got %d\n", sizeof a_header, n);
X+     pexit("file header too short: ", file_name);
X+   }
X+   if (a_header.xa_magic == FMAGIC)
X+     *sepid = 0;
X+   else if (a_header.xa_magic == IMAGIC)
X+     *sepid = 1;
X+   else
X+     pexit("not Xenix a.out FMAGIC or IMAGIC. FIle: ", file_name);
X+   if (a_header.xa_entry != 0)
X+     pexit("nonzero entry point. FIle: ", file_name);
X+   *text_bytes = a_header.xa_text;
X+   *data_bytes = a_header.xa_data;
X+   *bss_bytes  = a_header.xa_bss;
X+   *sym_bytes  = a_header.xa_syms;
X+ #else
X    /* Read first 8 bytes of header to get header length. */
X***************
X*** 263,264 ****
X--- 364,367 ----
X    *bss_bytes  = (unsigned) head[BSS_POS];
X+   *sym_bytes  = (unsigned) head[SYM_POS];
X+ #endif
X  }
X***************
X*** 333,340 ****
X  
X!   if (cum_size % 16 != 0) pexit("MINIX is not multiple of 16 bytes", "");
X    fsck_org = PROG_ORG + cum_size;       /* where does fsck begin */
X    ip = 0;
X!   cs = fsck_org >> CLICK_SHIFT;
X    if (sizes[FSCK].sep_id)
X!      ds = cs + (sizes[FSCK].text_size >> CLICK_SHIFT);
X    else
X--- 436,444 ----
X  
X!   if (cum_size % clicksize != 0)
X! 	pexit("MINIX is not multiple of clicksize bytes", "");
X    fsck_org = PROG_ORG + cum_size;       /* where does fsck begin */
X    ip = 0;
X!   cs = fsck_org >> HCLICK_SHIFT;
X    if (sizes[FSCK].sep_id)
X!      ds = cs + (sizes[FSCK].text_size >> HCLICK_SHIFT);
X    else
X***************
X*** 344,348 ****
X    sectrs = (unsigned) (all_size / 512L);
X  
X    read_block(0, ubuf);          /* read in boot block */
X!   ubuf[(SECTOR_SIZE/2) - 4] = sectrs + 1;
X    ubuf[(SECTOR_SIZE/2) - 3] = ds;
X--- 448,454 ----
X    sectrs = (unsigned) (all_size / 512L);
X+   if (all_size % 512 != 0)
X+      ++sectrs;
X  
X    read_block(0, ubuf);          /* read in boot block */
X!   ubuf[(SECTOR_SIZE/2) - 4] = sectrs;
X    ubuf[(SECTOR_SIZE/2) - 3] = ds;
X***************
X*** 367,368 ****
X--- 473,477 ----
X   * can't load DS from data space, but it can load DS from text space.
X+  * Write the offset of the symbol table for each progam into location 2 of
X+  * its code space, for the debugger. No one was expecting this, but is is
X+  * the only available unused space.
X   */
X***************
X*** 370,375 ****
X    int i, j;
X!   unsigned short t, d, b, text_clicks, data_clicks, ds;
X!   long data_offset;
X  
X    /* See if the magic number is where it should be in the kernel. */
X    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
X--- 479,485 ----
X    int i, j;
X!   unsigned short t, d, b, s, text_clicks, data_clicks, ds;
X!   long text_offset, data_offset;
X  
X    /* See if the magic number is where it should be in the kernel. */
X+   text_offset = 512L;
X    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
X***************
X*** 384,391 ****
X          b = sizes[i].bss_size;
X          if (sizes[i].sep_id) {
X!                 text_clicks = t >> CLICK_SHIFT;
X!                 data_clicks = ((unsigned long)d + b) >> CLICK_SHIFT;
X          } else {
X                  text_clicks = 0;
X!                 data_clicks = ((unsigned long)t + d + b) >> CLICK_SHIFT;
X          }
X--- 494,504 ----
X          b = sizes[i].bss_size;
X+ 	s = sizes[i].sym_size;
X          if (sizes[i].sep_id) {
X!                 text_clicks = t >> click_shift;
X!                 data_clicks = ((unsigned long) d + b + s) >> click_shift;
X! 		put_word(text_offset + SYM_OFFSET, d + b);
X          } else {
X                  text_clicks = 0;
X!                 data_clicks = ((unsigned long) t + d + b + s) >> click_shift;
X! 		put_word(text_offset + SYM_OFFSET, t + d + b);
X          }
X***************
X*** 395,396 ****
X--- 508,510 ----
X          put_byte(data_offset + 4*i + 3L, (data_clicks>>8) & 0377);
X+         text_offset += (unsigned long) t + d + b + s;
X    }
X***************
X*** 399,403 ****
X    if (sizes[KERN].sep_id == 0)
X!         ds = PROG_ORG >> CLICK_SHIFT;   /* combined I & D space */
X    else
X!         ds = (PROG_ORG + sizes[KERN].text_size) >> CLICK_SHIFT; /* separate */
X    put_byte(512L + DS_OFFSET, ds & 0377);
X--- 513,517 ----
X    if (sizes[KERN].sep_id == 0)
X!         ds = PROG_ORG >> HCLICK_SHIFT;	/* combined I & D space */
X    else
X!         ds = (PROG_ORG + sizes[KERN].text_size) >> HCLICK_SHIFT; /* separate */
X    put_byte(512L + DS_OFFSET, ds & 0377);
X***************
X*** 419,430 ****
X    init_org  = PROG_ORG;
X!   init_org += (long)sizes[KERN].text_size+sizes[KERN].data_size+sizes[KERN].bss_size;
X    mm_data = init_org - PROG_ORG +512L;	/* offset of mm in file */
X    mm_data += (long) sizes[MM].text_size;
X!   init_org += (long)sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size;
X!   fs_org = init_org - PROG_ORG + 512L;   /* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X!   init_org += (long)sizes[FS].text_size + sizes[FS].data_size + sizes[FS].bss_size;
X    init_text_size = sizes[INIT].text_size;
X!   init_data_size = sizes[INIT].data_size + sizes[INIT].bss_size;
X!   init_org  = init_org >> CLICK_SHIFT;  /* convert to clicks */
X    if (sizes[INIT].sep_id == 0) {
X--- 533,546 ----
X    init_org  = PROG_ORG;
X!   init_org += (long)sizes[KERN].text_size+sizes[KERN].data_size+sizes[KERN].bss_size + sizes[KERN].sym_size;
X!   /* this code was awful and is worse after adding sym_sizes */
X    mm_data = init_org - PROG_ORG +512L;	/* offset of mm in file */
X    mm_data += (long) sizes[MM].text_size;
X!   init_org += (long)sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size + sizes[MM].sym_size;
X!   fs_org = init_org - PROG_ORG + 512L;	/* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X!   init_org += (long)sizes[FS].text_size + sizes[FS].data_size + sizes[FS].bss_size + sizes[FS].sym_size;
X    init_text_size = sizes[INIT].text_size;
X!   init_data_size = sizes[INIT].data_size + sizes[INIT].bss_size
X!                  + sizes[INIT].sym_size;
X!   init_org  = init_org >> click_shift;	/* convert to clicks */
X    if (sizes[INIT].sep_id == 0) {
X***************
X*** 433,436 ****
X    }
X!   init_text_size = init_text_size >> CLICK_SHIFT;
X!   init_data_size = init_data_size >> CLICK_SHIFT;
X  
X--- 549,552 ----
X    }
X!   init_text_size = init_text_size >> click_shift;
X!   init_data_size = init_data_size >> click_shift;
X  
X***************
X*** 450,453 ****
X--- 566,575 ----
X    if (mag != FS_D_MAGIC) pexit("mm data space: no magic #","");
X+   mag = (get_byte(mm_data+3L) << 8) + get_byte(mm_data+2L);
X+   if (mag == 0) mag = HCLICK_SHIFT;	/* old mm */
X+   if (mag != click_shift) pexit("mm click_shift does not match kernel's", "");
X    mag = (get_byte(fbase+1L) << 8) + get_byte(fbase+0L);
X    if (mag != FS_D_MAGIC) pexit("fs data space: no magic #","");
X+   mag = (get_byte(fbase+3L) << 8) + get_byte(fbase+2L);
X+   if (mag == 0) mag = HCLICK_SHIFT;	/* old fs */
X+   if (mag != click_shift) pexit("fs click_shift does not match kernel's", "");
X  
X***************
X*** 496,497 ****
X--- 618,628 ----
X  
X+ 
X+ /* this should be used instead of paired put_byte()'s */
X+ put_word(offset, word_value)
X+ long offset;
X+ unsigned word_value;
X+ {
X+   put_byte(offset, word_value % 256);
X+   put_byte(offset + 1, word_value / 256);
X+ }
X  
END_OF_FILE
if test 16217 -ne `wc -c <'toolsdif/build.c.cdif'`; then
    echo shar: \"'toolsdif/build.c.cdif'\" unpacked with wrong size!
fi
# end of 'toolsdif/build.c.cdif'
fi
echo shar: End of archive 10 \(of 10\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: wors...@ditmela.oz.au

			  SCO's Case Against IBM

November 12, 2003 - Jed Boal from Eyewitness News KSL 5 TV provides an
overview on SCO's case against IBM. Darl McBride, SCO's president and CEO,
talks about the lawsuit's impact and attacks. Jason Holt, student and 
Linux user, talks about the benefits of code availability and the merits 
of the SCO vs IBM lawsuit. See SCO vs IBM.

Note: The materials and information included in these Web pages are not to
be used for any other purpose other than private study, research, review
or criticism.