Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!zaphod.mps.ohio-state.edu!mips!apple!uokmax!munnari.oz.au!murtoa.cs.mu.oz.au!ditmela!latcs1!stephens From: stephens@latcs1.oz.au (Philip J Stephens) Newsgroups: comp.sys.apple2 Subject: Re: apple // and multitasking, perfect together! (!!!!!!!!!!) Message-ID: <7377@latcs1.oz.au> Date: 7 Mar 90 15:21:04 GMT References: <14298@phoenix.Princeton.EDU> <17861@boulder.Colorado.EDU> Organization: Comp Sci, La Trobe Uni, Australia Lines: 73 In article <17861@boulder.Colorado.EDU>, Christopher Hassell writes: > > For timed interrupts: > > One can compile around a break-point-table 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. 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 > <\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/><\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/>