Post by Paul SchlyterPost by Michael J. MahonPost by Paul SchlyterLoading runtime libraries "as needed" as you suggest here would
require relocation of machine code to the addresses currently
avaiable - and code relocation is another weak point of the 6502....
I agree that it is non-trivial, and I know of no Apple BASIC compiler
that emits assembly code, which would solve that problem simply by
appending the required runtime routines to the assembly.
There are ways to handle it without reassembly, like writing
location-independent 6502 code (not bad for short non-self-modifying
routines), but they can cost speed, which is a problem.
Actually, Apple once made an effort to use the "R" file type in Apple
DOS, for relocatable 6502 object code. That code was not executable
though until it had ben processed by a linker.
There was even a third-party Linker utility, which could be used with
any Apple II assembler. Linker required you to follow specific
conventions in your assembly code, to mark and name entry points,
calls to external routines, and to mark blocks of code, relocatable
data, and non-relocatable data. You could then build a library of
routines, where each routine resided in its own binary file. Linker
linked it all together into one signle binary file, and could relocate
library modules but only by even multiples of 256 bytes.
I have a technique that I use to relocate short routines, that is
also restricted to page boundaries. I don't think I've ever seen
it used by others, even though it's pretty obvious.
I assemble the code at some arbitrary page origin, then scan the
code (I use a BASIC histogram program) looking for unused byte values.
(In any routine less than one page in length, there must be unused
byte values, of course.) I then change the page origin to one of
those unused values and re-assemble.
When I load the module, I use a trivial relocator that scans for
the byte value that now uniquely marks the high bytes of relocatable
addresses, and replaces them with the new page number.
This is extremely fast, can be combined with "move" code, if that
is required, and requires almost no logic.
If several modules are to be relocated in a single program, the
"magic" value can be stored at a fixed point in the module code
where the relocation loop can find it easily. (Often a module
starts with a short vector of JMPs to entry points, and the high
byte of the first such JMP is a natural place.)
This relocation technique can often be used successfully with modules
several pages long, but then it *is* possible for every byte value to
be used, so it may not work without some "fiddling" (that may need
redoing if the module source is altered).
Post by Paul SchlyterPost by Michael J. MahonPost by Paul SchlyterPost by Michael J. MahonMy point is that there are no BASIC compilers that I know of for
the Apple II that will compile *directly* to *in-line* machine code.
Indeed very true --- and I don't think you'll find such a BASIC
compiler for any other system either. They all have runtime libraries.
Of course, every language system has runtime libraries for complex
operations, but many Apple compiler writers seem to have been so
concerned with code expansion that they made their implementations
little more than calls to interpretive execution routines.
With only 48K RAM available, that's an understandable trade-off.
If there is only one way, that's probably what is required.
It is a shame, though, that no one ever addressed the "speed" side
of the space/speed tradeoff.
Post by Paul SchlyterPost by Michael J. MahonPost by Paul SchlyterNevertheless, Applesoft programs compiled with Expediter II runs many
times faster than the same program run on the Applesoft Interpreter.
It would be quite interesting to see comparisons of code generated
by various compilers for the Apple II. I expect there are some
significant differences.
Such comparisons were made back in the 1980's, and as far as I
remember, Microsoft's TASC (The AppleSoft Compilter) was the winner in
runtime speed but was much slower than all the others in compilation
speed. Expediter II (the "Einstein" compiler) came second in runtime
speed, and was among the fastest in compilation speed.
It's slow compile speed was no doubt a result of it being itself a
TASC-compiled Applesoft program! (This is clear if you enter the
monitor and take a look in memory--the runtime is obvious.)
Many would consider this a case of taking self-compilation a step
too far. ;-) But it is interesting to contemplate an Applesoft
compiler written in Applesoft. And it does keep the writers honest,
since the compiler must be able to compile itself--a pretty large
program exercising much of the language.
I'd love to find the source code for TASC! It is unique, AFAIK.
One could attempt a de-compilation, but the original program would be
a treasure!
Post by Paul SchlyterPost by Michael J. MahonPost by Paul SchlyterPost by Michael J. MahonIf you really feel you need the "level" of BASIC and the speed of
machine language, then your best approximation will probably be one
of the BASIC-like macro assembler packages. I believe that Nibble
offered such a package (maybe "Macrosoft"?).
If you really need that speed, you should forget about the Apple II
and go for a modern computer instead! An interpreted language on a
modern CPU runs much faster than even the most skillfully hand
optimized assembly code for the 6502 -- after all, Apple II emulators
nowadays run some 10+ times faster than the original hardware.
Sure, but that goes a bit beyond the scope of both this forum and
the OP's question...
There's quite a gap between the speed of interpreted Applesoft,
the speed of machine code on an Apple II, and the speed of modern
machines--plenty of room for applications in each speed range.
What I meant is that it's not really fun to strain the ability of your
hardware, e.g. by writing huge programs which need 4711 chained modules
to fit at all. Back in the early 1980's it could be understandable,
because then perhaps you couldn't afford more powerful hardware. Today
that situation is drastically different.
This is true for many practical purposes--but in this forum we are a
cadre of folks who 1) love Apple II's, 2) enjoy a challenge, and
3) are amused by puzzle solving. ;-)
BTW, I couldn't agree more about the practical difficulties in
organizing a complex overlay scheme. It's hard enough to get a
*correct* organization (that doesn't overwrite needed info), but
getting an *efficient* organization is really difficult.
Some programs have a structure that naturally suggests a simple
overlay/chain structure, but many large programs do not.
-michael
NadaNet networking for Apple II computers!
Home page: http://members.aol.com/MJMahon/
"The wastebasket is our most important design
tool--and it's seriously underused."