
Easy 6502 - Learn the 6502 Assembly Language - n8agrin
http://skilldrick.github.com/easy6502/index.html
======
mechanical_fish
It's fun to see people being encouraged to relive my youth. And 6502 assembly
is indeed a nice, compact thing to learn.

Though I think the most valuable thing I learned from studying assembly was
actually about higher-level languages: How function calls work, and the
mechanism of stack frames. This discussion doesn't reach quite that far, and
actually I'm not sure how one would work such things into a discussion of 6502
assembly – I learned about them in the context of 680x0 assembly. Back in my
6502 days, I never even encountered a compiler, so I never had the chance to
disassemble a C or Pascal program. (To this day I can't name a 6502-based C
compiler, though I'm sure they existed someplace. I knew about Pascal
compilers, but I never got my hands on one; back in the 1980s compilers
actually cost money.)

~~~
pjmlp
> back in the 1980s compilers actually cost money

They still do, only in Linux/BSD land they do not.

After all, people have to bring bread back home.

~~~
tluyben2
You can find free compilers for (almost) everything on every OS. What do you
mean with Linux/BSD land here?

And bringing bread home by making compilers; can you point out a commercial
compiler that 'brings bread home' besides the Visual Studio compilers (which,
actually, do not bring that bread; you can download the compilers for free)?
I'm curious as I thought paid compilers currently are niche and don't make the
companies selling them enough to actually pay more than maybe 1 person working
on it full time, if that. Maybe Intel is making enough of pure compilers to
actually call it a business?

~~~
pjmlp
I mean that having compilers with 100% full support is something that only
happens in open source land.

All commercial UNIX vendors sell their compilers. Even in Solaris case, the
EULA does not allow you to sell software done with their "free" compiler.

Intel compilers are not free for Mac OS X and Windows.

All the SDKs for game development from the console owners are not free.

The express editions of Visual Studio compilers are limited in which
optimizations they offer, libraries and supported processor targets.

The compilers from Portland group for HPC.

The compilers from CodePlay for the game industry.

Even the compilers from Apple can be said that they are not free, after all
you're paying indirectly for them when you buy a Mac Developer's license.

~~~
wglb
The xcode download that I use to build lots of stuff cost $0.

~~~
pjmlp
And how much did you pay for your Mac when compared with a PC with the same
technical specifications?

Plus, last time I checked you need to pay to be able to have proper access to
all developer information, <https://developer.apple.com/programs/mac/>.

Please read properly what I wrote, "paying indirectly for them", do you know
what _indirectly_ means?

~~~
duskwuff
> Plus, last time I checked you need to pay to be able to have proper access
> to all developer information

You checked wrong. Developer docs for production versions of Mac OS and iOS
are all available for free with Xcode. You only need to pay for membership to
the developer program, which gets you access to prerelease OSes (and related
documentation), and lets you distribute your applications through the App
Stores.

------
colanderman
I recommend also the 6809 as an example of another very well-designed
processor from the same era. Most notably, it has post-increment and pre-
decrement addressing, and basic 16-bit arithmetic support.

<http://www.textfiles.com/programming/CARDS/6809>

<http://en.wikipedia.org/wiki/Motorola_6809>

The modern Atmel AVR is in many ways a spiritual successor to the 6502 and
6809:

<http://en.wikipedia.org/wiki/Atmel_AVR_instruction_set>

(That said, I cut my teeth on the 6502 and it will always have a spot in my
heart!)

~~~
daeken
About two years ago I picked up 6809 assembly while writing an emulator for
it, to assist in reversing a device built around a 6809. Amazingly simple
processor/architecture.

~~~
wglb
Kind of reminds one of the PDP-11 architecture.

------
kghose
We were taught on the 8085. We had these cute little kits that were hinged
wooden boxes that you opened up. They had all the circuitry exposed which was
awesome, a 4 or 6 digit 8-segment LED display and a numeric keypad. Sometimes
the kits would go on the fritz and the most common solution was to press all
the chips into the sockets. Did I mention it was awesome.

My proudest/excitingest moment with them was at the end of the semester when I
implemented a long division program on them. It would take two numbers and
output the decimal fraction to an arbitrary number of digits using long
division.

Aaah!

------
bitcracker
> So, why would you want to learn 6502? It’s a dead language isn’t it? Well,
> yeah, but so’s Latin

6502 isn't dead, it has even been relaunched:

[http://www.h-online.com/open/news/item/Relaunched-
the-6502-m...](http://www.h-online.com/open/news/item/Relaunched-
the-6502-microprocessor-1422007.html)

6502 was my first processor, and it was real fun to learn Assembler. I used
also figForth and learned from the ground up how it was implemented. Amazing
days!

Today Assembler isn't fun anymore.. I don't even know the exact name of my
current quad core :)

Could it be that FPGA programming will be the next golden age of "Assembler"?
Content industry works hard to lock computer hardware with DRM. So if we want
to keep our freedom then we'll have no other choice than to build our future
computers ourselves - again.

~~~
sliverstorm
I question the idea that homebrew CPUs on FPGAs are the future of desktop
computing. Core IP availability aside, FPGAs are _very_ expensive.

Also, FPGAs are typically configured with an HDL, which can be likened more to
C than assembler.

~~~
radarsat1
I'm not sure about that, you can get small FPGA kits for less than $100 now,
and the software is free and multiplatform (but not open). The DE0-nano dev
kit is an example, it's about $80. I imagine the availability of things like
the Raspberri Pi will bring prices down even further.

Aside from similar to some programming language, HDL is pretty interesting to
learn in its own right. (Although I disagree that it's like C. It's more like
a declarative language for circuits, though it's true that you can stick
imperative-like code in there. But treating it like C is a recipe for
problems.)

~~~
hatcravat
Sure, but you can get an MSP430 dev kit (stripped down IDE for C; USB dev
board with a programmer and a few buttons and LEDs; a couple devices in DIP
packages) from TI for $4.30 plus shipping.

Also, most microcontroller companies provide all the specs you need to roll
your own end-to-end software for the device. Aside from specifying the machine
language (so you can write your own compiler), they also have app notes for
programming the onboard flash via JTAG or another interface. With programmable
logic, it seems like the only parts that don't require the vendor's own
programmer and synthesis software are legacy SPLDs like 22v10s.

------
Smerity
This is an excellent introduction -- thanks for posting it :) I teach high
school students programming as part of a summer camp and this is a perfect
resource for students who are already further along and want another
challenge. The introduction to assembly will help them in their later careers
and 6502 assembly is likely less of a shock than any recent ASM.

With the 32x32 display they could even do some simple graphics to stretch
themselves :)

~~~
elliottcarlson
Besides simple graphics, the original Prince of Persia was developed in 6502
assembly - the source has even been released recently:
[http://jordanmechner.com/blog/2012/03/prince-of-persia-
sourc...](http://jordanmechner.com/blog/2012/03/prince-of-persia-source-code-
found/)

------
cjauvin
Very elegant and well done! I recently went through the process of learning
6502 C64 ASM (an unfulfilled childhood dream), by writing a simple Tetris
clone:

<https://github.com/cjauvin/tetris-c64>

The basic concepts came very easily (with a quick skim through Jim
Butterfield's ML book), but I struggled a bit more with the C64 hardware
intricacies: zero page addressing, IRQs, double-buffering to avoid flickers,
etc. This was a very interesting and enlightening experiment (in terms of the
perspective it sheds on modern-day tools and languages), and I plan to write
about it soon.

~~~
vidarh
It's pretty unusual to use double-buffering on the C64 - wastes memory. You'll
find a lot of code times screen updates to the raster interrupt to either do
updates during virtual blank, or start updates after the portion of the screen
in question was updated. Of course that assumes you can do the updates in one
frame, so you will find exceptions.

~~~
cjauvin
In fact, I don't know if what I did really corresponds to "real" double-
buffering: at any point, the next move is created in an alternate buffer,
which, when ready, is then switched as the visible portion of the video RAM
(at vblank, using the raster interrupt). It works ok, but it's also quite
possible that this mechanism might be a bit overkill.

------
dizzib
I'm attempting to finish writing my unpublished BBC micro game 'Zen' written
in 1988...

<http://www.youtube.com/watch?v=Gg8Dtod83qA>

It's so much fun developing in 6502 assembler again!!!

~~~
mpclark
The cool thing is that, as a BBC game, it well sell only slightly fewer copies
today than it would have in 1988. You've lost nothing by waiting :)

Game looks great, btw!

------
davepeck
So much fun, thank you. Some of my earliest programming was on a C64 with the
Merlin Assembler -- this brought me back _and_ brought a big grin to my face.

------
n-gauge
This brought back my collage days! I had job coding Z80 ASM to control
electronics and RS232 data links... such fun :)

People would give you such funny looks when they saw you staring into a
terminal of hex and you pointing out .. ahh that 3E CF needs to be 3E D3 :)

Best thing is that I ending up knowing all the op-codes and most of the
instruction timings of by heart (which made interfacing to those 16 x 2 line
LCD modules easier)

NMI anyone?

------
mjcohenw
Both the Apple II and the Commodore PET used the 6502.

I'm amazed that these were not mentioned in the original article.

I wrote a bunch of 6502 code for Micro Technology Unlimited's music and
graphics boards for the PET, and even wrote my own assembler in PET Basic. Fun
Times!

------
facorreia
I remember the 6502 from the days the Apple II hit the market. It was huge
back then. Strangely, the article lists a number of 6502 systems down to
Futurama's Bender but doesn't mention Apple II.

------
sethish
If anyone would like to use this to write emulation instructions for Prince-
of-Persia II [0], I would be happy to merge them into the github repo [0].

[0] <https://github.com/jmechner/Prince-of-Persia-Apple-II>

------
Kelliot
This brings back memories of painful Friday morning lectures in yr1 of uni! XD

------
ColinWright
As a humorous aside, from Futurama the robot Bender allegedly runs on a 6502.

------
hcarvalhoalves
Educational hacks are the best hacks. Bonus points for historical value!

------
michaelochurch
This is cool stuff. A few noob questions:

I notice that the 0x00-ff memory space has no 0xff byte and that 0xfe seems to
change a lot, but it's not explained. What's going on here? What's in 0xfe and
why is 0xff not shown?

I noticed that there's no multiplication operator. Does that mean that
multiplication was performed using looping addition? What about division,
floating-point, et al?

~~~
loganfsmyth
* Not sure I follow this question. The zero page (address 0x00-FF) can store any values 0x00-FF.

* This is an old processor, so it doesn't support fancy stuff like multiplication and division and floating-point. Generally you just try to avoid multiplication whenever possible, or keep it to powers of 2, since that can be done with shift operations. You can do multiplication using looped addition, but if you were to implement it you'd want to use a constant-time binary multiplication algorithm instead.

~~~
michaelochurch
If you open the Monitor in the first example and step through it in the
debugger, the byte at address 0xFE changes at every step. This doesn't seem to
be documented and it's not clear to me why it's doing that.

Moreover the content of 0xFE keeps changing even after execution stops (if you
keep hitting the "step" button).

0xFF isn't even listed, but a load from that address seems to work (with value
0x00). [ETA: actually, that seems to be a quirk of the Monitor's initial
config. If you set "length" to 100 instead of ff, you can see byte 0xFF in the
monitor. Nothing wrong or weird there.]

~~~
loganfsmyth
Examining it a bit more, The value in 0xFE can be ignored. It is just a random
value. I don't know why.

There is a function called 'setRandomByte' that is called on every debugger
step, but it has no comments so it may just be leftover debugging logic.

------
Zenst
For a assembly language designed for humans they sure did like there 3 letter
TLA's.

How hard would it of been to have STORE_ADDRESS instead of STA.

To realy learn a assembly language you realy need to write code and to write
code you realy have to have a project/purpose.

Now 6502 is one of the oldest assembly languages still in active use as they
still do very well in the microcontroler sector. Though that said ARM is also
in that area and alot cheaper to obtain ARM compatable kit. ARM was born out
of frustrations/limitation with the original 6502 CPU and in that may be a
better more practical use of your educational time.

That all said - every programmer of any language should at least learn/play
with one assembly language sometime in there life, maybe one or two. I
remember after my ZX81 I opted for the Oric-1 over the Spectrum just becasue
it had a different CPU (6502) and after that I opted for the AtariST (6800)
and a amstrad PC (X86).

Also inventing your own CPU/assembler is not as hard and intimidating as alot
will think. All are very rewarding and a good use of your time on a rainy day.

~~~
ralph
STA is `store accumulator' not address. Would you have liked to type
STORE_ACCUMULATOR with the high frequency that the instruction occurs on an
editor that had no auto-complete? Even reading it is slower than STA. And
having them be all three letters meant assemblers could pack the text into
memory in fixed-length records; every byte mattered.

Here's the table of ARM mnemonics in the source to Acorn's BBC BASIC for the
ARM.
[https://www.riscosopen.org/viewer/view/castle/RiscOS/Sources...](https://www.riscosopen.org/viewer/view/castle/RiscOS/Sources/Programmer/BASIC/s/Assembler?rev=1.16#l105)
For the 6502, space was tight enough that it was packed to less than three-
bytes per mnemonic.

ARM was born from Acorn's frustration with 16-bit CPUs that they considered as
successors to the 6502, e.g. 68000, not the 6502.

~~~
vidarh
> And having them be all three letters meant assemblers could pack the text
> into memory in fixed-length records; every byte mattered.

As much as I agree with using the mnemonics, this is a bogus argument. Even
C64 BASIC tokenized stuff before storing it, because there's no reason to
store the name at all. In fact, if you prefer, the 6502 instruction set is
small enough to represent it in the assemblers editor as a single byte index
into an array. Or you could just use the opcode itself.

~~~
ralph
BBC BASIC tokenised BASIC keywords before the line was stored in memory, e.g.
PRINT was represented by a single byte. Some tokens needed more than one byte,
especially in later versions.

But I'm talking about assembler here. BBC BASIC has a built-in assembler, e.g.
6502, Z80, or ARM, depending on the CPU it's running on. The assembler source
in the BASIC program is _not_ tokenised on input but stored as plain text.
Instead, when those lines of BASIC, since that's what these embedded lines of
assembler, wrapped in [...], are, get run the machine code is assembled at the
address in BASIC's P% integer register variable and P% is moved on. At that
point of execution BASIC must hunt for the mnemonic, stored in the "tokenised"
BASIC line as plain text, in its table; the table I reference in the case of
ARM BASIC. That table can be laid out as it is because each mnemonic is three
characters long, e.g. mov, ldr, stm, and bic.

You mixing tokenising BASIC, which BBC BASIC did, and the embedded ARM
assembler, which it didn't, and then adding in an "assembler's editor", and
there wasn't one of them. Just lines of BASIC program, 10, 20, ..., some of
which switched to assembler with a [.

~~~
vidarh
I'm not talking about the BBC specifically all - the specific system is
irrelevant - and so I'm not "mixing" anything. Many 6502 based systems _did_
have assembler editors; many more had "monitors" that would assemble line by
line on the fly - if not built in then as common extensions.

(in fact I did most of my M6502 assembly programming in a monitor, with a
notepad to keep track of where various functions started; it was first a
couple of years after a I started doing assembly that I got a proper macro
assembler for my C64, and even then exactly because "every byte mattered" it
was not at all uncommon to still stick to a monitor on a cartridge rather than
have a macro assembler "waste" precious memory for the assembler and source
text)

What I'm talking about is the general idea that longer keywords somehow would
prevent an assembler from using fixed length records to represent lines,
though reading it in context of what you wrote above I see your reference to
fixed length records referred to the table used for assembling, not to the
source lines in which case it makes slightly more sense to me.

Though not fully, as it'd be both faster and take less code to use custom
search code to match the input against the available opcodes than to insist on
a fixed length record - did a quick check and it should be doable to save at
least a dozen or two bytes and reduce the average search time significantly by
range checking and using lookup table for the first character. It might've
been convenient to write the code with fixed records, but it's far from
optimal in terms of either performance or code size, so it doesn't seem like
code size bothered them _that_ much in this case.

The "every byte mattered" applies to source too on these systems, and I
actually find it really curious that they went to the step of supporting
inline assembly but then didn't apply that optimization to the source given
the limited memory and performance of these systems. Especially since the
opcode itself makes a very obvious token candidate, potentially leaving the
"assembly" step itself reduced to mostly copying data and applying address
fixups.

