
Ways to implement computer languages on 6502s (1994) - 6502nerdface
http://www.dwheeler.com/6502/a-lang.txt
======
colanderman
Well, how much say do we have over the architecture? Paging/banking hardware
is pretty common on 6502-based systems. Such hardware decouples the virtual
address space (what the CPU sees) from the physical address space. Typically
they are used to extend memory space (e.g. the Apple //e's 80-column card) but
they can also be used as a mass indirection mechanism (e.g. the NES's various
"mappers", which granted are used more by its graphics coprocessor). The act
of paging is "instantaneous" since you are just setting a hardware register.

So if you are designing the hardware, give it an extra 4 KiB or so (16 pages),
mapped through a paging circuit to the zero page. On entry to a function,
increment the current page; on exit, decrement. Now you have a way to push all
"local variables" that is faster than even pushing all the registers. You
could even get fancy and XOR bits 7-4 of the page register with bits 4-7 of
the paged address lines, so the compiler can choose anywhere from 16 256-byte
frames up to 256 16-byte frames.

~~~
arbee_mame
There's also the Apple ///'s approach to almost-transparent banking on a 6502.
The hardware could redirect the zero page to (almost) anywhere in the 64K
address space (foreshadowing the 65C816's movable zero page), and it
maintained a sort of second zero page called the "X" page at a fixed offset
from the zero page. Then on any indirect access to memory through the zero
page, it would check the corresponding byte in the "X" page and if it was
valid it would use it as additional address bits. As implemented in the ///,
programs could thus directly access up to 512KB without doing any traditional
banking or paging.

Of course, it was also possible to do traditional banking on the /// so that
program code could reside anywhere in the 512K, but I thought the X page thing
was pretty neat when I finally figured it out.

~~~
colanderman
Great tidbits! I'm reminded also of the 6809's movable "zero" page (the
"direct page"), though it has a 16-bit stack register so the trick isn't
really necessary.

~~~
cmrdporcupine
Usable for other good things tho, since zero page access is a single cycle
operation on both 65xx and 6[8|3]09

------
keithnz
I remember... WAY back in the day... On the Ataris there was a language called
Action! It was pretty good!

[https://en.wikipedia.org/wiki/Action!_(programming_language)](https://en.wikipedia.org/wiki/Action!_\(programming_language\))

~~~
floggle17
Action! rocked! So fast to compile and run. Too bad it came along too late in
the Atari lifecycle to matter. It's big trick was to disallow recursion, which
meant local variables and function args/results could be allocated statically,
which worked around the 6502's limitations.

------
russellsprouts
Coincidentally, I was just reading this the other day. I've been programming
for the Nintendo NES. The most common high level language that people use for
NES Homebrew development is C with cc65[1]. The output of the compiler is
passable, but C is just not well suited to the 6502 processor. Eventually I'd
like to write a compiler for a high level language that used these ideas.

[1] [http://cc65.github.io/cc65](http://cc65.github.io/cc65)

~~~
lebration
I've wanted to implement a better C compiler myself, and I think it would work
better if it were built from the ground up instead of from Small-C, as cc65
was.

I would split the parameter and computation stacks, instead of using one as
cc65 does. The parameter stack would work the same as cc65's, but the
computation stack would be a FORTH-like stack indexed with the zp,X addressing
mode.

Second, I would have it build an AST instead of having the parser generate the
code. This would open doors to big optimizations, such as automatically
detecting when to use 8-bit ops (complicated by C's promotion rules), etc.

Finally, I would implement far pointers for memory-banked systems--most
prominently the NES, which cc65 doesn't handle banking on as far as I know.

Another think that could be done is using the zero page as a bank of
16/32/etc. registers and treat the 6502 like a RISC.

cc65 is an amazing project that's enabled many developers. It's Small-C
pedigree is limiting though, and inefficient on a machine that it wasn't
designed for.

~~~
lifepillar
You may be interested in PLASMA:

[https://github.com/dschmenk/PLASMA](https://github.com/dschmenk/PLASMA)

------
cmrdporcupine
"Use fixed zero page locations for locals and parameter passing, simulating a
conventional CPU with a large register file. This eliminates most stack
operations, except for saving/restoring the zero page"

The 65c816 allows the "zero page" (called the direct page there) to be
relocated anywhere in the lower 64k. So if one targets that platform the
saving/restoring operation could simply be one of pushing/popping the direct
page location to/from the stack when entering or exiting function stack
frames. Then just keep all program code above the 64k boundary.

------
larsbrinkhoff
> I wanted a language that would be (a) faster to program in (than assembly)
> but be (b) fast when running. It needed to be pretty efficient.

Forth. Problem solved.

~~~
jhbadger
The danger of Forth, is that much like with LISP, as soon as a programmer gets
competent in it, they think "You know what the world needs? Another version of
my favorite programming language".

~~~
progman
Isn't this a general attitude? I think it applies to many programming
languages, in particular at developers who know only their one favorite
language.

I learned Forth on a 6502 besides Basic and Assembler, and it was the language
with the best performance/memory ratio. It was about 10 times slower than
Assembler, and very efficient in memory consumption. Memory was a really big
issue at that time. And Forth as a programming language is not bad. You just
need a lot of discipline (like at Lisp) because it is so extremely powerful. I
wonder why Forth isn't used for firmware since buggy code could be exchanged
at runtime.

~~~
jhbadger
True, although Forth and Lisp have the advantage of making (at least toy
implementations) a project of a few spare evenings due to their simplicity.

I was also into Forth in the 1980s on the Apple ][, and have always meant to
get back into it (or one of the new Forth-y languages like Factor) one day.

------
PieterH
I implemented a forth based language on C64 in 1983, it was tiny and fast. The
6502 was well suited to this. The REPL nature of forth languages is also
perfect for machines with limited offline storage.

------
djmips
Not 6502 but the Zardoz 65816 compiler from back in the day (early nineties)
had different memory models and one of the best allowed you to use the direct
page register (essentially a moveable zero page) to access local variables in
your functions. If you made some concessions to how you coded your C, you
could end up with reasonably efficient code all things considered. It would be
pretty cool to see a C like language that compiled efficiently for a stock
6502.

------
6502nerdface
The author has more notes on the same topic elsewhere on his website, too
(including reviews of Forths for 6502, PLASMA, and others):
[http://www.dwheeler.com/6502/](http://www.dwheeler.com/6502/)

------
nemoniac
So if you implemented a lisp on the 6502, you could run it on this emulator
and then it'd be turtles all the way down?

[https://github.com/kingcons/cl-6502](https://github.com/kingcons/cl-6502)

------
orionblastar
I think 6502 machines can do better with a version of BASIC that can compile
into machine language binary files. One that has advanced commands for moving
sprites and checking for collisions, etc. A BASIC compiler if you will?

~~~
lazyjones
There was this: [https://en.wikipedia.org/wiki/Turbo-
Basic_XL](https://en.wikipedia.org/wiki/Turbo-Basic_XL)
[https://sites.google.com/site/ataripal/turbobasicxl](https://sites.google.com/site/ataripal/turbobasicxl)

I won't ever forget typing in seemingly endless columns of hex numbers from a
magazine to obtain both the interpreter and the compiler... (here are some
original scans & documentation:
[http://www.tmeyer.de/atari/index.html](http://www.tmeyer.de/atari/index.html)).

~~~
scarface74
I always wondered why they didn't make disks available for sell with the
programs on them? The two assembly programs I remember the best having to type
out myself for the Apple //e was one that added double high resolution
graphics commands to Applesift Basic and one typing out shape tables of
letters so you could easily mix text with graphics.

~~~
abecedarius
At least in the earlier years disk drives were high-end equipment. I started
out with cassette tape, and it's much less reliable.

------
pmontra
This is a 2009 revision of a 1994 article.

------
wobbleblob
I once had a pascal compiler for a 6502 machine:

[http://www.acornelectron.co.uk/info/electron/acornsoft/Spasc...](http://www.acornelectron.co.uk/info/electron/acornsoft/Spascal.html)

~~~
brassic
Acorn also did Forth and Lisp, though the Lisp was interpreted.

