[comp.sys.apple2] apple // and multitasking, perfect together!

tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) (03/07/90)

Intro: "NJ and you, perfect together" is some random slogan that Gov. Kean
and NJ advertisements use all the time. 

I was (am) thinking long and hard about implementing a multitasking
operating system on the apple //. Let me state right away that I don't
ever expect to accomplish anything useful with such an operating
system; it would be way too slow. I just think it would be a neat
thing to have around.

A multitasking operating system implies the existence of a multi-user/
permission structure in the hardware itself. That is, the processor of
a multitasking machine must be able to differentiate between at least
two modes, one "privileged" and the other "user". I know that the VAX
has four levels of privilege, while the MIPS (in its RISC-like wisdom)
has just two. The 6502 obviously has just one "mode"!!!

I was wondering how much fun it would be to at least get a program
started on the 6502 which could *emulate* a more serious processor and
then to build an operating system on top of that. I was not sure what
to call this processor, and I was not even sure what kind of processor
architecture I needed, so I ended up calling it "BISC" (Byron's
Instruction Set Computer) since that is certainly what it is going to
be.

So far, I've decided on a few implementation details: following the
lead of the MIPS, all memory accessing instructions will be of the
load/store variety only (that is, all arithmetic, etc. instructions
must take registers or immediate arguments as their operands). There
will be 32 16-bit registers at the disposal of the kernel, and another
32 registers available for any particular process. (The registers will
actually be addresses in zero page---it turns out it's better to "hard
wire" some register-register instructions to operate on zero-page
addresses with X offset and to swap the registers in and out on
context switches than to operate on each process's registers directly
in high memory.) The machine will have a 32-bit address space, but
relative addressing modes will cut down on code size.

I know this sounds really freakish, but eventually it might be nice to
port gcc (so that it cross compiles) from VAX-->BISC (or any suitable
host where gcc already exists and runs). This is not as unreasonable
as it sounds, since the BISC architecture would not diverge far from
the standard (powerful) processors which we have at our disposal
today. It should not be too hard to tailor gcc, in other words. Of
course, BISC would run as slow as molasses on a cold Alaskan winter
morning, but that's another story. After gcc exists, then one can
easily write code for BISC and download it down and run it. The I/O
routines would be performed in native 6502, of course, but the
routines themselves would be blind to BISC programs; they would simply
execute an appropriate "call kernel" instruction. BOS (you guessed it,
"Byron's Operating System") will be written in GNU C, for the most
part, with the exception of the really critical parts, which could be
written in straight BISC.

What does anyone think? Is this project stupid, or is it way cool? A
CS friend of mine told me that my crowning achievement would be to
boot up the apple // and then see the word

login:

on the screen :-). 
-- 
Just try taking your VAX down to Jiffy-Lube these days!
			
Byron "Bo knows parallel computational geometry" Rakitzis. 
				(tbrakitz@phoenix.Princeton.EDU)

pnakada@oracle.com (Paul Nakada) (03/07/90)

This is actually kind of cool, the concept of all memory acces being
done through load and store instructions.  That would allow
implementation of virtual memory quite easily though these
instructions.  Just map all of the pseudo machine's memory into non
volatile (above $0800) and use any additional memory for paging.  

I think that some sort of elementary VM is necessary for any type of
multiprocess OS on the //.  

Will your BISC instruction set be a p-machine? (interpreted) or
compiled directly to assembly.  The former is more suited to a VM
environment.

-Paul Nakada
pnakada@oracle.com

tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) (03/07/90)

In article <PNAKADA.90Mar6163032@pnakada.oracle.com> pnakada@oracle.com (Paul Nakada) writes:
>
>This is actually kind of cool, the concept of all memory acces being
>done through load and store instructions.  That would allow

This is exactly what MIPS does. It's not my idea, but it's obviously
suitable under the circumstances.

>
>I think that some sort of elementary VM is necessary for any type of
>multiprocess OS on the //.  
>

I am aiming at a full blown VM!! This is my dream: to hack up a card
for one of the expansion slots which would communicate with the phone
port in the back of my Mac SE... The SE would act as the //'s
filesystem! That way the // could tell the card to fetch page x, and
then get on with other business while all that stuff is done by the
other hardware. The memory copies can then be done really fast with a
tight loop. I want to steer clear of Disk ][ if I'm going to implement
VM. 

>Will your BISC instruction set be a p-machine? (interpreted) or
>compiled directly to assembly.  The former is more suited to a VM
>environment.
>

BISC will definitely be interpreted. With an MMU and other sundry
interrupt handlers (keyboard etc.) it would be insane to compile the
BISC into 6502. I am aiming for code which is really compact at the
BISC level. That's another reason for the RISC design, paradoxically
enough. If I allow only register-register arithmetic instructions,
then I can squeeze a whole class of opcodes into two bytes, if I'm
careful. (though that might mean having only 16 16-bit registers)

>-Paul Nakada
>pnakada@oracle.com

-- 
Just try taking your VAX down to Jiffy-Lube these days!
			
Byron "Bo knows parallel computational geometry" Rakitzis. 
				(tbrakitz@phoenix.Princeton.EDU)

eloranta@tukki.jyu.fi (Jussi Eloranta) (03/07/90)

In article <14298@phoenix.Princeton.EDU> tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) writes:
>I was (am) thinking long and hard about implementing a multitasking
>operating system on the apple //. Let me state right away that I don't
>ever expect to accomplish anything useful with such an operating
>system; it would be way too slow.

Too slow, 6502 stack (256 bytes), no MMU, small amount of mem., ... ,
forget it..

>A multitasking operating system implies the existence of a multi-user/
>permission structure in the hardware itself.
....
>has just two. The 6502 obviously has just one "mode"!!!
>

Well not all multi-tasking systems need this... 

>I was wondering how much fun it would be to at least get a program
>started on the 6502 which could *emulate* a more serious processor and
>then to build an operating system on top of that. I was not sure what
>to call this processor, and I was not even sure what kind of processor
>architecture I needed, so I ended up calling it "BISC" (Byron's
>Instruction Set Computer) since that is certainly what it is going to
>be.
>

Huh?! Even slower! ... I would suggest to forget the whole thing...
May be 68xxx series would be a more reasonable processor to start with.

Jussi




-- 
============================================================================
Jussi Eloranta               Internet(/Bitnet):
University of Jyvaskyla,     eloranta@tukki.jyu.fi
Finland                      [128.214.7.5]

hassell@boulder.Colorado.EDU (Christopher Hassell) (03/07/90)

<14298@phoenix.Princeton.EDU> tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) 
....
# I was (am) thinking long and hard about implementing a multitasking
# operating system on the apple //. Let me state right away that I don't
# ever expect to accomplish anything useful with such an operating
# system; it would be way too slow. I just think it would be a neat
# thing to have around.

I think that with a proper amount of planning... any operating system can
actually do some decent work... because it is merely a STRUCTURE for
computation... and not reallllly meant to be the main job of the computer <to 
run stuff WITH operating system support>.

# A multitasking operating system implies the existence of a multi-user/
# permission structure in the hardware itself. That is, the processor of
# a multitasking machine must be able to differentiate between at least
# two modes, one "privileged" and the other "user". I know that the VAX
# has four levels of privilege, while the MIPS (in its RISC-like wisdom)
# has just two. The 6502 obviously has just one "mode"!!!

Again... as someone noted.. AAAALLLL that that reallly does is simply simply
provide the safety-net we talked about: stopping errant code.  If we give up
that... then everything else begins to come into focus .. as being possible.

# I was wondering how much fun it would be to at least get a program
# started on the 6502 which could *emulate* a more serious processor and
# then to build an operating system on top of that. I was not sure what
# to call this processor, and I was not even sure what kind of processor
# architecture I needed, so I ended up calling it "BISC" (Byron's
# Instruction Set Computer) since that is certainly what it is going to
# be.

Ahhhhhh... I dunno.  I don't think that the 6502 is allll that bad...
especially because also one can always benefit from adapting to the actual
machine.  Processor capabilities are never really the problem.... its just the
organization.. the virutal-memory... basically its the support that is the
problem.

My idear follows many things... and they're ALLLL oriented around smarter
compilers <again...something we DON'T have for the apple//>.  

SO... the things the apple DON'T have in hardware :  
	timed interrupts,
	protected modes and system-interrupts for them.
	virtual <and FAST> hardware-paged memory, or relative address-modes

There is actually something to be said for the actual philosophy in the
Apple... "make it all accessible and software will do the rest".

As for actually producing the above effects via the smartest compiler known to
mankind <almost>:

	For timed interrupts:
		<easily replacible and much better if someone HAPPENS to have 
			a clock :->

		One can compile around a break-point-table <literally> which
		gives positions in code where break-instructions can be quickly
		put and where the code can be restored after control has been 
		handed to the kernel. <for re-entry>

		Loops need at least one per iteration if they are long enough
		to be time-consuming.

	For protected modes:
		Check code <heavy compiler duties> for when it dereferences a
		pointer.. or accesses an array-element.  Add in error-checking 
		code specifically for this.  For pointers... it would be best 
		to just do an AND of the top-byte... detecting the page where 
		it points. <this is STILL faster than running pseudocode>

	For virtual-memory-paging:
		Yup... software would have to do... but but but.. again.. if 
		    all callpoints are recorded along with jumps etc.... <no 
		    software-defined jumps should be allowed except to points 
		    which are predefined and accessible> <tough 
		    type-checking!>... one could include little "guards" at 
		    jumps and stuff... (added code) which ask the kernel if 
		    the jumped-to part of the program is loaded in.

		    It would take alot of programmer-smarts to know where to 
		    allow the program to be split up <into pieces which can be 
		    run in memory one at a time... the compiler should then
		    install the protection to allow other pieces to be brought
		    in>.

		FORKING: For the wierd aspects of program-connecting... forks 
		    .... pipes... stuff like that... one should know 
		    BEFOREHAND which programs will be called in.. and load 
		    them in when the program is loaded in.  They would be a 
		    PART of the program-image itself.

		    The problem with forking in MANY ways is simply that it
		    treats entire programming sections as if they were
		    subroutines.  The disk-system is what suffers under this
		    folly ... but who's gonna argue if they can still make it
		    work fast enough. :->

		    If one doesn't know specifically which programs will be
		    called <a shell or something else> then the computer should
		    make reservations specifically to do its work there.

		STACKS: For dealing with program-stacks with many processes... 
		    its a good bet that the puny 256-byte stack won't handle
		    it.  The best way to do things .. then .. is to put
		    pointers on the stack for program-variables <with external
		    stacks for their variables> and let every procedure-call
		    actually put its own pointer on the stack... and take it
		    off when its done.  

			The 256-byte aspect of the stack would be VERY tough 
			to deal with in order to make sure things don't go too 
			far... but maybe it could be copied out when big
			changes occur <system/shell changes over to program>

	Memory-Management: Relocatibility and Code
		
		As everyone can guess... it would be a PAINFUL thing to have
		non-relocatible code.  

		A possible method is to "groom" the code for non-normal
		relocations for everything... by (ugh) MODIFYING it according 
		to another-compiler table of absolutes <maybe storing it in a
		certain form... and changing it to another address only if
		necessary>.  Then programmers would still have the speed of 
		absolute-direct operations.. but they needn't actually ask the 
		system constantly for where its variables go NOW.

		Otherwise..... code should be ALWAYS relocatible.. with
		branches instead of jumps.. and maybe even a standard single 
		"jsr" address with a loaded in branch/jump-tables just for 
		accessing a program's subroutines.  (one could leave the
		procedure-number as a plain byte after the call) <sound memory 
		hungry yet?>

	Otherwise... pointers should determine where everything goes and
	system-allocation could take care of the rest <programs would have to
	ask for their own EXPECTED allocation... in order to do any work>

OKAY OKAY... I know... a totally and utterly disGUSTING mess of self-modifying
code... 8-year compilation times and LOTS of time/memory simply for loading it 
in in the first place! <a hacker's dream>

But it could work (tm)......... :-> :-> :->.

# What does anyone think? Is this project stupid, or is it way cool? A
# CS friend of mine told me that my crowning achievement would be to
# boot up the apple // and then see the word

# login:

# on the screen :-). 

Sigh... There is alot to be said for your idea... esPECIALLY if it can encode
instructions better <in higher-level> so as to make programs themselves
smaller.  Maybe it could be the basis for MOST programs.. with only a few
allowed to actually be in assembly.

Why do I ALMOST sound like I'm serious.... maybe because I am??? <scary scary!>

# -- 
# Just try taking your VAX down to Jiffy-Lube these days!
# 			
# Byron "Bo knows parallel computational geometry" Rakitzis. 
# 				(tbrakitz@phoenix.Princeton.EDU)

Yo Kno BO Kno
Self-Modifying-Compiler-Intensive-Incredibly-Small-and-Inefficient-O/Ss.

All we need to do now is make device drivers!!!!!  <okay okay... keep them in
memory only because they're mostly ROMS!>

Beware... someday in your future may be:
	Apple //e UNIX v2.3  (around 1995)
### C>H> ### { uunet!rutgers!sunybcs , ncar , nbires } !boulder!tramp!hassell

stephens@latcs1.oz.au (Philip J Stephens) (03/07/90)

In article <17861@boulder.Colorado.EDU>, Christopher Hassell writes:
> 
> 	For timed interrupts:
> 
> 		One can compile around a break-point-table <literally> which
> 		gives positions in code where break-instructions can be quickly
> 		put and where the code can be restored after control has been 
> 		handed to the kernel. <for re-entry>

   An intriguing idea.  This is ridiculously easy to implement: All the OS
needs to do is save the registers (and possibly the interrupt address and
status register from the stack), then restore everything before JMPing back
into the program.  Very good idea.  I had never thought of using BRK
instructions for that purpose.
   For even more simplicity, the compiler really only needs to insert BRK
instructions after every _atomic_ statement (not compound ones) of a high
level language.  This ought to provide reasonable response time, and will
minimize the amount of context saving that is needed to switch processes.
 
> 	For protected modes:
>               [details deleted]
>       For virtual-memory-paging:
>               [details deleted]
>       [other implementation details deleted]

   How about this for an idea: get the compiler to generate code to reside
in a fixed area of RAM (e.g. $800 onwards). 
   All branch, JMP and JSR instructions that fall inside a common page are
normal 6502 code.  All other such instructions become JSR's to the OS followed
by the required address, which the OS can then handle.  
   All data references are left untouched.

   All running processes are copied into a disk file that represents the
programs entire memory "image" at any given time.
   The OS loads up the current "program" page of a process into it's true
address range, along with all of the "data" pages that could possibly be
accessed by the code in the "program" page.  It then lets it run until it
hits a breakpoint, or when a JSR to the OS is executed.
   Thus the OS must scan the program page, looking at all of the data
references to see what range the access could lie in.  For absolute modes,
this is obvious.  For indexed absolute modes, you need to cater for the
entire 256 bytes of offset (thus a maximum of 2 pages of data to load). 
Indirect modes are more difficult: the compiler must generate a JSR to the
OS whenever the base address is modified, so that the OS can load in the
2 pages that are necessary at that time.
   Better still, the compiler could generate a list of "data" pages to be
loaded for each "program" page.  This might speed up the loading of "data"
pages considerably.

   Whenever processes are switched, the OS saves all of the data pages 
currently loaded for that process on it's image file, and then loads up the
approapiate pages for the next process.
  
   This technique gives maximum speed, with minimum code modification.  Only
loading up the required data pages will slow it down, and jumps out of the
current page.  I think you'll find however that in any standard "program"
page, references to data will fall within a reasonable number of "data" pages. 
(Particually since most high-level languages are stack oriented).  Jump's
out of pages would be few and far between.

                    --------------------------------

   So there you have it!  One day ago, I was complaining that it would be
too difficult to implement; today someone comes up with a brainstorm - and
now anything is possible :-) :-) :-)

   Any improvements, or comments on gross mistakes ;-) welcome.

</\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\></\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\>
<  Philip J. Stephens                ><   "Many views yield the truth."        >
<  Hons. student, Computer Science   ><   "Therefore, be not alone."           >
<  La Trobe University, Melbourne    ><          - Prime Song of the viggies   >
<\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/><\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/>

toddpw@tybalt.caltech.edu (Todd P. Whitesel) (03/08/90)

tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) writes:

>I was (am) thinking long and hard about implementing a multitasking
>operating system on the apple //.

I did a lot last year, I came up with some novel ideas, but the homework
cruch has kept me from getting anywhere substantial. My idea was first to get
a load-time self-linking development system going, and then to figure out how
to extend to it do run-time linking, loading, and multitasking.

>Let me state right away that I don't
>ever expect to accomplish anything useful with such an operating
>system; it would be way too slow. I just think it would be a neat
>thing to have around.

Where's your ambition? I want a cheap text editor, term program, and assembler
all available at the same time. I can think of too many uses for just the
editor and term program once protocol transfers or macro-type features are
supported.

On the contrary, I don't think it would be too slow, unless your overhead was
atrocious, and I have faith that that is not a problem. The 6502 machine state
is pretty damn small, but unless you use a 65816/802 then your stack and zero
page management overhead is murder (this can be avoided by setting a large time
slice, but that may produce yucky interactive response). I think that the best
way to accomplish such a system is to find some method of writing low-context
programs that use software conventions to avoid the problem.

>A multitasking operating system implies the existence of a multi-user/
>permission structure in the hardware itself. That is, the processor of

Bull. The hardware system only comes in when you try to implement a real system
for real programs which are not proven. If the software is restricted enough to
allow things like interrupts, context switches, etc., to operate properly and
efficiently, then you don't need a lot of hardware (a timed interrupt is sort
of required, but many common expansion cards can be used to to accemplish this)
to make the system work.

>a multitasking machine must be able to differentiate between at least
>two modes, one "privileged" and the other "user". I know that the VAX
>has four levels of privilege, while the MIPS (in its RISC-like wisdom)
>has just two. The 6502 obviously has just one "mode"!!!

That's if the CPU model is the only programming model you have. Code which
is handed all of its pointers, or drivers which must be used to access the
hardware, provide a 'priveliged' mode by the virtue of the fact that they are
the only code which may execute these instructions, since no one else may
count on the hardware addressses, etc., that the drivers contain and isolate.

The entire Mac O/S uses this principle, and compatibility problems on new Macs
are primarily due to violations of it. (The Mac O/S should have made everyone
else run in 68000 user mode from the start, but that's another issue.) 32 bit
clean is a coding standard developed by Apple to avoid these problems.

>I was wondering how much fun it would be to at least get a program
>started on the 6502 which could *emulate* a more serious processor and
>then to build an operating system on top of that. I was not sure what
>to call this processor, and I was not even sure what kind of processor
>architecture I needed, so I ended up calling it "BISC" (Byron's
>Instruction Set Computer) since that is certainly what it is going to
>be.

You're not giving the 6502 enough credit, either: you can write very good
programs on the 6502 -- IF you exploit its full capabilities, which NO ONE
really does these days. The Atari 2600 game designers often used the X reg
as a data stack pointer into zero page, and since you can perform almost
any zero page operation on zp,X it makes a great place to store counters and
other saved information like pointers which must be preserved across subroutine
(ok, function) calls.

>So far, I've decided on a few implementation details: following the
>lead of the MIPS, all memory accessing instructions will be of the
>load/store variety only (that is, all arithmetic, etc. instructions
>must take registers or immediate arguments as their operands). There

The 6502 already does this if I am not mistaken.

>will be 32 16-bit registers at the disposal of the kernel, and another
>32 registers available for any particular process. (The registers will
>actually be addresses in zero page---it turns out it's better to "hard
>wire" some register-register instructions to operate on zero-page
>addresses with X offset and to swap the registers in and out on
>context switches than to operate on each process's registers directly
>in high memory.)

Hey, that's how the Sweet-16 interpreter worked... Only it had one set of
16 16-bit registers and they were fixed at zero page 0-$1F.

>The machine will have a 32-bit address space, but
>relative addressing modes will cut down on code size.

Now you've got a (still vaporous) 65832 but with more registers.

>course, BISC would run as slow as molasses on a cold Alaskan winter
>morning, but that's another story. After gcc exists, then one can

I see why it would be slow. Forcing one CPU architecture to emulate another
always seems to do this.

>What does anyone think? Is this project stupid, or is it way cool? A
>CS friend of mine told me that my crowning achievement would be to
>boot up the apple // and then see the word

>login:

Well, I'd rather boot up and see something better than 'login', like
a nice banner and some soundsmith music while the O/S loads in seconds from an
EPROM disk.

You've got the right idea, though, but I still think it would be better to
write a good native 6502 compiler (I have low opinions of the currently
available efforts, you see) and to port everything over with that. The drivers
and ML portion of the O/S would of course have to be written in 6502 but how
much of unix is really machine code?

(Personally I'd like to see an O/S that is like unix but more micro oriented,
not in terms of addressing space or number size, but in terms of the needs
it is written to address, like interactive response time, graphics and sound,
simplicity, and above all efficiency so it will fit on the machines we want it
to run on and be reasonably fast. O/S tasks don't have to hog a heck of a lot
of CPU, but improperly written code always will.)

I see the Apple as a simple and efficient machine, and I'd like a real O/S that
sees those as design principles. Unix comes very close but has some compromises
I don't like, the worst of these is how generic it is. I realize that that is
a major strength of unix but I bet we could improve on it by just handling
special cases properly. That doesn't make much sense unless I give an example:
I want to be able to identify the hardware through the O/S so that I can take
direct control without crashing the system, and this means locks and
arbitration so that programs using the hardware directly can avoid trampling
on each other.

How feasible does this sound? I'm convinced it's possible, but haven't had the
time to develop any concrete applications of it :(

Todd Whitesel
toddpw @ tybalt.caltech.edu

toddpw@tybalt.caltech.edu (Todd P. Whitesel) (03/08/90)

hassell@boulder.Colorado.EDU (Christopher Hassell) writes:

>OKAY OKAY... I know... a totally and utterly disGUSTING mess of self-modifying
>code... 8-year compilation times and LOTS of time/memory simply for loading it 
>in in the first place! <a hacker's dream>

I disagree here. Self-modifying code is only bad in a system which has no use
for it. Very compact (and clever) self-modifiying code can and has been made
to work on a variety of machines, however it does make assumptions about the
memory in which the code runs. On a 6502 system none of these assumptions are
a problem.

I also think that the compiler would not be a real problem either, because the
algorithm used to do the grunge work of the compiler is more a determinant than
the CPU speed.

I often wonder what is really inadequate: the hardware, or the people who write
compilers for it.

I see lots of evidence to convince me that the compiler writers are much more
to blame, because when the hardware doesn't make everything nice and easy it
is a lazy programmer who says "oh well, the machine just can't do that" as
opposed to the hacker who figures out a way or says "I can't find a way to do
that" because he decides it is not physically possible. Programming is my
favorite science because it has room for artistic expression and at the same
time it is cool and precise.

Unfortunately, to far too many people it is simply a way to get paid. I admire
most the people who become part time programmers so that they can use their
computer as a tool. The Apple has a long history of this, and it's what I like
best about it. It's why I don't want an Amiga or Mac or PC, I want to work for
Apple so I can make a //f and then buy one.

Todd Whitesel
toddpw @ tybalt.caltech.edu

toddpw@tybalt.caltech.edu (Todd P. Whitesel) (03/08/90)

stephens@latcs1.oz.au (Philip J Stephens) writes:

>   For even more simplicity, the compiler really only needs to insert BRK
>instructions after every _atomic_ statement (not compound ones) of a high
>level language.  This ought to provide reasonable response time, and will
>minimize the amount of context saving that is needed to switch processes.

Excellent idea. I was wondering if the BRK opcodes could be defined such that
(say) $80-FF were reserved for O/S functions, and 0-$7F were defined to point
into a 'process subroutine table' or something like that which would be
generated by the compiler and would be modified stack-style for each block of
code that uses its own. In fact, the compiler could just have each function
big enough to need the table call the O/S to save & restore the subroutine
table pointer. This allows you to use the BRK/IRQ vector and provides excellent
task-switching opportunities, plus it is inherently relocatable. It does bear
the cost of the subrountine calls but any program large enough to need it will
take long enough to make the call overhead negligable. One exception to this
would be heavy recursion and the only efficient solution I can think of is
simple tagged relocation for JSRs and JMPs.

>   So there you have it!  One day ago, I was complaining that it would be
>too difficult to implement; today someone comes up with a brainstorm - and
>now anything is possible :-) :-) :-)

Watch out, sooner or later we'll have to put our coding skills where our
mouths are.. :)

Todd Whitesel
toddpw @ tybalt.caltech.edu

madd@world.std.com (jim frost) (03/08/90)

I'm getting into this rather late, but here's my two cents.

I thought about doing such a thing for awhile and checked into some
historical methods of accomplishing it.

First, you can provide memory protection through emulation without a
lot of problems.  Whenever you want to use a non-relative instruction,
replace it with a BRK sequence which is interpreted and checked for
validity.  While the interpretation will take some time, it's not all
that bad and does give the protection you want in a multitasking OS.

Second, you can provide a non-preemptive multitasking scheme without a
lot of problems.  Many other systems do this with good results --
witness the Mac multifinder.  Non-preemptive means that you don't
interrupt a process at a random time -- it gives up control
(implicitly or otherwise).  Most of the time this is done during
system calls such as I/O routines (which I assume you wish to
provide).

There are a few problems with implementing a multitasking system under
the Apple hardware other than those I've discussed.  The biggest is
its very primitive I/O.  Since I/O is handled in software and not
hardware, you don't get to spend I/O time running something else.
This is a severe performance bottleneck, especially since you don't
have the memory to do I/O caching with periodic synchronization.

Happy hacking,

jim frost
saber software
jimf@saber.com

jazzman@claris.com (Sydney R. Polk) (03/09/90)

From article <7377@latcs1.oz.au>, by stephens@latcs1.oz.au (Philip J Stephens):
> In article <17861@boulder.Colorado.EDU>, Christopher Hassell writes:
>> 
>> 	For timed interrupts:
>> 
>> 		One can compile around a break-point-table <literally> which
>> 		gives positions in code where break-instructions can be quickly
>> 		put and where the code can be restored after control has been 
>> 		handed to the kernel. <for re-entry>
> 
>    An intriguing idea.  This is ridiculously easy to implement: All the OS
> needs to do is save the registers (and possibly the interrupt address and
> status register from the stack), then restore everything before JMPing back
> into the program.  Very good idea.  I had never thought of using BRK
> instructions for that purpose.
>    For even more simplicity, the compiler really only needs to insert BRK
> instructions after every _atomic_ statement (not compound ones) of a high
> level language.  This ought to provide reasonable response time, and will
> minimize the amount of context saving that is needed to switch processes.

This will also drastically slow your code down.  Compiled code on the II
is slow even with a good compiler.


-- 
Syd Polk           | Wherever you go, there you are.
jazzman@claris.com | Let the music be your light.
GO 'STROS!         | These opinions are mine.  Any resemblence to other
GO RICE!           |  opinions, real or fictitious, is purely coincidence.

jazzman@claris.com (Sydney R. Polk) (03/09/90)

From article <1990Mar8.014339.3976@spectre.ccsf.caltech.edu>, by toddpw@tybalt.caltech.edu (Todd P. Whitesel):
> hassell@boulder.Colorado.EDU (Christopher Hassell) writes:
> 
> I also think that the compiler would not be a real problem either, because the
> algorithm used to do the grunge work of the compiler is more a determinant than
> the CPU speed.
> 
> I often wonder what is really inadequate: the hardware, or the people who write
> compilers for it.
> 
> I see lots of evidence to convince me that the compiler writers are much more
> to blame, because when the hardware doesn't make everything nice and easy it
> is a lazy programmer who says "oh well, the machine just can't do that" as
> opposed to the hacker who figures out a way or says "I can't find a way to do
> that" because he decides it is not physically possible. Programming is my
> favorite science because it has room for artistic expression and at the same
> time it is cool and precise.
I have actually written a compiler.  It is a nightmare.  An easy chip
to write for in nice, but even then, generating efficient code in such
a recursive environment is enough to drive one loopy.

Compiler design is a whole area of work in computer science; writing for
a machine that has a many limitations as the 6502 is well-nigh impossible
if you want good code.  It would be much more reasonable, but still a
pain in the ass, to write something for the 65816.  After all, the 80286
architecture is very similar, and there exists many good compilers for
it.  However, there are STILL problems that the compiler write writing
for DECs, SUNs, and MACs don't usually have to deal with.


-- 
Syd Polk           | Wherever you go, there you are.
jazzman@claris.com | Let the music be your light.
GO 'STROS!         | These opinions are mine.  Any resemblence to other
GO RICE!           |  opinions, real or fictitious, is purely coincidence.

gwyn@smoke.BRL.MIL (Doug Gwyn) (03/10/90)

In article <1990Mar8.014339.3976@spectre.ccsf.caltech.edu> toddpw@tybalt.caltech.edu (Todd P. Whitesel) writes:
>I often wonder what is really inadequate: the hardware, or the people who write
>compilers for it.

In the case of the 6502 family, the hardware architecture really does
adversely constrain the quality of correct implementations of high-level
languages.  (It is easier to produce an implementation that doesn't
properly or fully support the language.)  This has nothing to do with
the motivations of the compiler writers; the relation between machine
arhcitecture and language implementation quality is well known in the
industry.

Anybody who doubts this should try to produce his own implementation
before passing judgement on others'.

jason@madnix.UUCP (Jason Blochowiak) (03/14/90)

toddpw@tybalt.caltech.edu (Todd P. Whitesel) writes:
>tbrakitz@phoenix.Princeton.EDU (Byron Rakitzis) writes:
>> [oh, just gobs of stuff deleted]
>You're not giving the 6502 enough credit, either: you can write very good
>programs on the 6502 -- IF you exploit its full capabilities, which NO ONE
>really does these days.

	I dunno about the 6502, but as far as the '816 goes - I dare you to
look at John Brooks' code and say that again :) He knows the CPU and the rest
of the machine on a first-name basis. Happens not to be my coding style, but
I'm still quite impressed with it.

>>So far, I've decided on a few implementation details: following the
>>lead of the MIPS, all memory accessing instructions will be of the
>>load/store variety only (that is, all arithmetic, etc. instructions
>>must take registers or immediate arguments as their operands). [...]
>The 6502 already does this if I am not mistaken.

	I believe you are mistaken. For example, it's possible to do something
like:
	lda	<zp1
	and	<zp2
where, in a load/store only type architecture, you'd do something like:
	lda	<zp1
	ldb	<zp2
	and	a,b
where 'b' is some new register (and, yes, I'm aware of the pseudo-register
B on the '816).

>Todd Whitesel
>toddpw @ tybalt.caltech.edu


-- 
                      Jason Blochowiak - jason@madnix.UUCP
or, try:         astroatc!nicmad!madnix!jason@spool.cs.wisc.edu
       "Education, like neurosis, begins at home." - Milton R. Saperstein