Hacker News new | past | comments | ask | show | jobs | submit login
Easy 6502 – How to get started writing 6502 assembly language (skilldrick.github.io)
207 points by sebg on Jan 5, 2017 | hide | past | favorite | 84 comments



Thank you for posting this. This reminds me of my favorite book.

This is for those who want another good assembly book, I would recommend Assembly Language and Computer Architecture Using C++ and Java[0]. You will learn a lot from this book and not only assembly language. You'll learn about a theoretical computer H1, how to use a simulator, debugger, how a CPU can be built from scratch, how a compiler generates code by using a stack then slowly improving the instruction set architecture and make it more efficient in generating assembly code. You'll also learn how an object oriented program can be converted into assembly language. You'll learn how a C program is linked to other object files. You'll learn how to implement your own instruction set. You'll learn how to build an assembler... I can go on and on but this book is much more detailed. Just get this book and have fun reading it. I mean it.

[0] - https://www.amazon.com/Assembly-Language-Computer-Architectu...


> Assembly language is the lowest level of abstraction in computers - the point at which the code is still readable.

For simple enough instruction sets it was not unheard of that people memorized the actual opcodes. In school, at the transition from terminals to micros, a friend of mine walked up to one of the new Commodore 6502 machines and entered a simple program in hex directly into the monitor program. For a while I had the common opcodes for the RCA 1802 memorized, due to working with a project board without an assembler (writing assembly on paper, then hand assembling into opcodes, then keying in the opcodes).

There's no returning to those days and I wouldn't if I could, but I can't help but think that I was lucky to have experienced that for the knowledge and perspective.


> In school, at the transition from terminals to micros, a friend of mine walked up to one of the new Commodore 6502 machines and entered a simple program in hex directly into the monitor program. For a while I had the common opcodes for the RCA 1802 memorized, due to working with a project board without an assembler (writing assembly on paper, then hand assembling into opcodes, then keying in the opcodes).

Ha ha, nice. Early on in my learning programming, I got a book about the Commodore 64. Written by a 16 year old (!) kid from the UK (IIRC), it had, in Commodore BASIC, the complete listing (using POKE statements :) of an assembler program for the C64. I typed the program into a C64 I had access to, over some days (making mistakes with the hex codes in the middle of the listing, a couple of times, and having to start the whole thing over), and finally ended up with a working assembler. Then wrote some 6502 assembly language C64 programs using the assembler, including for simple graphics.

>There's no returning to those days and I wouldn't if I could, but I can't help but think that I was lucky to have experienced that for the knowledge and perspective.

Agreed - and a lot more along the same lines, later on DOS and Unix too :)


Interesting, just saw here:

https://en.wikipedia.org/wiki/MOS_Technology_6502

under section 1.5, "Computers and games", it says that:

The 6510, a direct successor of the 6502 with a digital I/O port and a tri-state address bus, was the CPU utilized in the best-selling[48][49] Commodore 64 home computer.

https://en.wikipedia.org/wiki/MOS_Technology_6510


We used to test each other about Z80 opcodes staggering home drunk from the pub late at night as teenagers...

LDIR? ED B0! LD HL,nnnn? 21! ...

Ah... those were the times ;)


You can still do that with MIPS and some of the other assemblers only used with embedded chips!

A lot of people in my computer organization class five years ago ended up memorizing most of them, since it was sort of a side effect of having to go from opcodes to assembler and back again on quizzes.


Woz famously hand-assembled the Apple ][ ROM, in fact.


Why do people write ][ for the Apple II? I've seen it in a bunch of places now.


Probably because that's exactly how it was written on the machine's original logo[1]. I think it changed later on, though.

[1] http://www.vintage-computer.com/images/apple2logo.jpg


It was also ][ on-screen.


Exactly that. It's how the machine announced itself at boot. You can see that right here:

https://www.scullinsteel.com/apple2/


Nice, thanks for adding that.

My first programming experience happened on an Apple ][ we had in my kindergarten classroom. It's been a long time since I've used one, though, so I didn't remember the on-screen logo.


A9008502


If it is 6502 code, it is in assembly language:

  A9 00      LDA #$00
  85 02      STA $02
But what is the intention of the code?


Looks more like an OEIS sequence identifier to me.


There is no OESIS sequence with this number, since by

> http://oeis.org/eishelp2.html

"The A-number (for example A000108) is the absolute catalogue number of the sequence. It consists of A followed by 6 [not 7!] digits."

Indeed:

> https://oeis.org/A9008502

"Sorry, the page you requested was not found"


My first real job was programming a Commodore PET for a merchant - in BASIC. When I needed searches to be faster I wrote a routine in 6502 assembler. Unfortunately I didn't have an assembler, so I hand-assembled my code using the instruction code chart from the back of a book. My "loader" was a chunk of BASIC code POKEing numbers into memory.

Can confirm that the 6502 instruction set is pleasantly simple. On the other hand, a similar experience can be had on some modern CPUs as well. I found the Atmel AVR's instruction set (as found in the Arduino and Raspberry Pi) to be similarly approachable.


Back in school (I studied electronics), our embedded programming course was done on 8085 machines with a hexadecimal keypad where you could enter data into memory a byte at a time. The assignments were done on pen and paper, we got a printout of the instruction set, a blank piece of paper and a description of what the program was supposed to do. We'd write the assembler code on paper, translate it by hand to hexadecimal using the instruction set reference and then load the resulting binary code by hand. You could pause execution with a button and the address and data buses were available on pins, so you could hook up a scope or logic analyzer to see what was happening under the hood.

Most everybody hated that class, but man did I love it. It was hands-down the most fun class in my studies. Would've been better with a 6502 though.

EDIT: Oh look, I found the machine. Apparently it was a HP 5036A Microprocessor Lab (learning computer): http://www.azur-electronics.com/Pages/hp_5036a_microprocesso...


I can't see how it would have been better with a 6502. The 8080 family had multiple clock cycles per instruction cycle, thus if you are hooking up a scope and watching, there is more going on to see, and if you grok what's happens at each clock transition, you will have learned more about timing and the internal propagation of signals through stages of logic gates. It's somewhat similar to CISC vs RISC, both may be elegant designs, but understanding more complexity is a greater intellectual puzzle and the 8085 had more microcode.


In high school, I used a similar setup from Heathkit with a 6800 processor.

http://www.vintage-computer.com/heathkit3400.shtml


Acorn System 1 for the Win

http://imgur.com/a/f7zZR

http://forum.6502.org/viewtopic.php?f=12&t=3286&hilit=acorn+...

(No I haven't built the replica yet - darn work/life balance)


Raspberry Pi is ARM, not AVR. And it's not really comparable to an Arduino since it runs a full OS.


Oops! I stand corrected. But no, the Raspberry Pi does not necessarily run a full OS. It can, and it certainly makes sense to do that, but it's very possible to run a standalone boot-loaded program on a Raspberry, just as OSes like FemtoOS will run on AVR architecture.


Yes, the combo of read/data and poke was the preferred way to combine Basic and assembly on the C64 also. Technical magazines like The Transactor consisted of program listings that were nothing but these statements and lots of numbers. I believe 169 is LDA, if memory serves...


Pi is ARM of course, but +1 for AVR. 6809 was nice too.


I loved 6809. It's the design of th instruction set that I loved, its simple consistency. That and the fact that it had a SEX (sign extend) function, and two stacks.


>On the other hand, a similar experience can be had on some modern CPUs as well.

There's absolutely no reason you couldn't constrain yourself to a subset of the instructions available on x86 and have a fairly equivalent experience as coding for a 6502.


Yes simple unless you had to add two numbers greater than 255 :)


16-bit arithmetic was not a problem, you just checked the carry flag.


I loved this so much that I bookmarked it to my home screen. I used to do 6502 assembly as a kid. My biggest achievement with it was creating a database application (I had spent the summer doing some data entry work with dBase and loved the idea).

I can't wait to get my son into all this stuff. 8-bit Basic first, then assembly. I think he's gonna love it and I love the fact that people still enjoy the 6502.

So much history and memories with the machines it powered..


I have similar fond memories programming games in 6502 for the Atari 800!


Original posting w/ comments: https://news.ycombinator.com/item?id=6345730


One of the first computers I designed and built was based on the 6502. It was a variant made by Rockwell. It was called R65F11. It came pre-loaded with FORTH in internal ROM.

One of the most challenging projects was designing a floppy disk controller from scratch (complete with the analog circuitry) to read and write to 5-1/4 and 8 inch floppy drives. Of course, I also had to write the driver and every other driver for the thing. In fact, I also had to write my own code editor.

The "pinnacle" was using a dozen of these to run a robot. They talked to each other over a serial loop.


That's sounds friggin awesome fun! FORTH on a '6502' may be nightmarish to some but not to me. So many new 'words' to make.


It wasn't bad at all. I don't remember all the details. I do remember it was a tremendous amount of fun. The part I forgot to add was that every single board was wire-wrapped.

I also had to design and make various peripheral boards, such as: LED numeric display, DC motor drivers, analog and digital I/O, etc.

The entire computer was based on a 44 pin interconnecting bus. The CPU board could then address and talk to up to 16 cards, all memory mapped. No FPGA's or PAL's, all LS-TTL logic.

Sometimes I think it would be neat do put together a Kickstarter project for a kit and lesson plan to that would teach people to build a similar computer from scratch. Start with logic design, on through hand-building boards, bootstrapping in assembly, bringing-up FORTH, bring-up mass storage, writing a text editor and then some applications. Not sure how much interest there might be on such a thing these days. I know I would have been all over something like that way back then.


I just bought an RC2014 kit ( http://rc2014.co.uk ), which bears some similarity to what you're talking about. A larger community making cards for that computer would be really cool.


That is almost exactly what my self-designed/built computers looked like. The baseboards were longer and used an edge connector and card format that was popular at the time in industrial applications:

https://en.wikipedia.org/wiki/Edge_connector

This would be a fun project to work on if I could set aside some time. FIRST robotics build season (http://www.firstinspires.org/) is starting this weekend. I mentor one of the local teams. This sucks-up most of my free time for a few months.

Adding to my to-do list.


Awesome, I hope you can find the time to do it. I don't suppose the popular industrial bus with edge connectors was STD Bus, was it?


Yes, STD, but I came up with my own pinout.


It's interesting to note that the 6502 is still in production in 40pin DIP and surface mount variants.

No doubt, a number of old stable designs still rely on it (I'd guess medical/scientific equipment).


Fwiw, the Tamagotchi toy line used the 6502 as of 2013: http://hackaday.com/2013/05/24/tamagotchi-rom-dump-and-rever...


Love your site. 6502 was great, very intuitive, very fast.

I learned it at 14 years old after finding out basic wasn't very good for coding graphics. Back then the speed improvement for 6502 was always amazing because there were not high quality C compilers (actually no compilers)

Imagine learning a new language, platform, with no Google or StackOverflow. It didn't seem like a big deal at the time but wow that must have been inefficient.

My bible for 6502 was this book that I think every cmdr programmer had:

http://www.ubbcentral.com/store/item/VIC-20-Programmers-Refe...

Of course there was no assembler, it was just typing in raw instructions and addresses. Anyone else used to leave NOP gaps to make adding instructions easier?


> Imagine learning a new language, platform, with no Google or StackOverflow.

To be fair, 6502 is a small, simple language. I learned 6502 back when I was 11-12 with little more than some .txt files, a lot of time, and a question or two answered by some very RTFM type folks. That one was not too hard overall, despite being my first language. I'd never ask someone to learn some new fancy language and framework without the internet, however.


All things considered, there were a lot of resources out there but you had to do some leg work. I subscribed to Compute! There were also a fair number of machine language programming books by the likes of Richard Mansfield and Jim Butterfield.

(Maybe it helped that I was in Toronto and there was a lot interest in Commodore computers)


My mother had a friend who just had her daughter die. I volunteered to help her clean up her house. I had a Commodore 64 and was learning how to program on it. She was going to throw away the Compute and Compute Gazette magazines, but I asked if I could have them instead. Changed my life reading them and learning how the games worked and changing them. Using joystick routines to make a menu in Basic to load programs off the floppy disk and execute the address for the sys command in the menu so the user doesn't have to do it.

It was so long ago I've forgotten most of it.


Man that brings back the memories: I had a Vic-20 and had learned how (through magazines) to program in BASIC. I had the Vic-20 manual, and for some reason could not conceptualize the link between assembly language and the op-codes. I remember the day I saw a BASIC program that poked the assembly op codes into RAM for a simple keyboard - WOW! suddenly the light went on in my head. Good times.


I remember those days :-) Back then after getting tired of typing raw instructions I wrote a very primitive assembler in basic (starting with 3.5K and counting down, it had to be primitive if I wanted any space left to run the generated machine code...)


My resource for learning 6502 machine language was the Apple ][ Reference Manual: http://www.classiccmp.org/cini/pdf/Apple/Apple%20II%20Refere...

which had appendices that covered the instruction set and opcodes, useful addresses, ROM listings, and all other kinds of useful stuff. What a great manual that was!


As a side-side note, there are (were) a lot of those key-ring LCD's/phototoframes that used a 6502 compatible chip, the ST2205U that provided no end of fun tinkering with it:

https://spritesmods.com/?art=picframe&page=1

http://forum.doozan.com/read.php?9,2435


I want to learn 6502. Unfortunately, it's a right pain getting a 6502-based machine to run. The efficient instruction fetching means you have to be really careful about wiring and memory fetch speed. And I don't have any old 6502 systems on hand. All I've got is a Gameboy, and that's somewhere between the Z80 and the 8080. So I'll probably learn that at some point (although the GB is basically the Z80 with all the good bits stripped out).


Not really. You can get up to about 1Mhz on a breadboard, and my wire-wrap SBC works at 4Mhz without any issues. If you did run into timing issues, you could just underclock the whole thing.


>Not really. You can get up to about 1Mhz on a breadboard, and my wire-wrap SBC works at 4Mhz without any issues.

That's true, but for a newbie like myself, it would be rather hard to get going.

Also, the current run of the W65C51 is majorly broken, which makes getting the project going even harder (most alternatives to the W65C51 are no longer sold).


I built my SBC without any prior experience. You pretty much just have to connect all the adress and data lines, and then figure out the chip selection logic. I used an MC68B50 for the UART, which can still be found very cheaply on eBay.


Huh. I guess it's worth a shot, then... I'll have to look into using a MAX232 for connecting it to my terminal, as well (I do, in fact, have a terminal: A Z19, in fact).

Might as well build a Z80 system while I'm at it. And Zilog's UARTs are quite nice, or so I've heard.


One thing I'd recommend is to try to find some 5V erasable EEPROMs, so you can reprogram it in-system wthout having to transfer it over to a dedicated (and expensive) programmer.

I went with a 12V-EEPROM at the time, so I had to write my own emulator to speed up my development cycles :)


I can't tell you how many hours I spent teaching myself ML (not assembler) during the early 80's on a PET4032.

Ya. I'm old AF.

But, it laid the groundwork for me so that I have a fundamental understanding of whats really going on with any language, and, processor. Once you learn ML (or assembler), learning new languages becomes an order of magnitude easier because of this understanding.


If you want a fun side project write a 6502 assembler. It's not nearly as hard as you might think! I wrote one in Python to be part of a game I was working on. I got it up and running in a day or so. It's something that improved my skills and was fun to work on!


Writing a 6502 emulator is also a lot of fun!

Shameless plug: https://github.com/DavidBuchanan314/6502-emu


I find x86 much more fun than 6502, for various reasons. It is much more common and what most computers run today. If you want to accelerate some application using SIMD instructions, you can actually do this. If you want to write a bootloader, you can do this. If you want to look at the disassembly of your favourite program.

Besides, I wouldn't say x86 is harder than 6502. You don't really 'learn' an assembly language anyway. You learn the most common instructions (loads, saves, arithmetic, branches and tests) and get a feeling for what kind of instructions there are. Now when you write something you use a reference and look up necessary instructions and look for new ones that might be useful.


There were few enough instructions in 6502 that you really could memorize them all (I did back in the day). That really isn't possible with a huge instruction set like in X86. Yes, as you say, you can look them up, but that's no fun.


I wrote a VT-100 emulator in 6502 in 1983. While it's a wonderful assembly language to write in (so simple) I have as much desire to write in 6502 again as I have drive on the Interstate in a Model-T.


Hey, are you me!? I wrote same for the Commodore 64; it ran in graphics mode with a bitmapped font to give an 80-column screen.

Wish I'd kept the code for posterity.


Mine was for a 40 column screen, you had to flip the screen back and forth to read all 80.


Everything is fun... once.


As a topic newbie I ask: what CPUs is this assembly targeted for? Why would I learn an assembly for a old CPU and use I with an emulator when I could learn assembly for modern CPUs and let it run on the metal?


Your question is addressed in the fourth paragraph at the link:

> "Then why 6502? Why not a useful assembly language, like x86? Well, I don’t think learning x86 is useful. I don’t think you’ll ever have to write assembly language in your day job - this is purely an academic exercise, something to expand your mind and your thinking. 6502 was originally written in a different age, a time when the majority of developers were writing assembly directly, rather than in these new-fangled high-level programming languages. So, it was designed to be written by humans. More modern assembly languages are meant to written by compilers, so let’s leave it to them. Plus, 6502 is fun. Nobody ever called x86 fun."


Odd... The dead reply under here looks like an excellent reply. I wonder what I'm missing...

Anyway, 6502 is a super easy processor to program on. Back in the old days (and maybe even still) universities often used non-existent processors for teaching assembly language programming and associated concepts. I learned 6502 as a child on my Apple II and even when I went to university, I always thought it was a much better first starting place simply because it lacks anything complicated at all.

To be honest, even though I have fond memories of 6502, if it were me, I might have chosen 6809 since it gives you a few more facilities and makes a couple of things a bit easier. But it's not crucial...

You can certainly learn using a more modern processor, but there is a lot more stuff to keep track of. The idea of starting with a super simple processor and then graduating to a more modern and complex processor makes sense to me.


As a kid I had a Vic 20 and then an Acorn Electron, so like you I learned 6502, but I agree that the 6809 was a much nicer CPU to learn. Refurbished ICs seem to be available, but as far as I know it is no longer manufactured.


The 6502 is actually still in production. However...

Modern assembly x86, or even modern ARM assembly, is significantly more complicated than 6502 assembly.

Starting with the 6502 will let you write working code more quickly and introduce you to the core concepts of assembly language programming.

More than this, even if you never write assembly, being aware of what a CPU instruction set looks like helps you grasp core concepts in C/C++.

If you're only ever going to write high level code (e.g. JavaScript) this probably isn't helpful. But as an aid to understanding how computers work, and what they are capable of, it can be really useful.


I doubt that. With 6502 you have so much byte fiddling to do; x86 (or 6809) is much easier once you need more than 8 bit pointers.

(I probably still have a turing-complete set of Z80 opcodes in my head.)


"On the metal" is kind of a hazy concept on modern systems. If you write x64 assembler and run it on Windows/Linux, is that really "on the metal"? If you don't consider it to be, then you have a lot of work to do in getting it to boot with the screen turned on and a usable keyboard.

Whereas in emulating a complete old system like a BBC micro it is far easier to get to the metal while still being able to use the display and peripherals.

"Assembler" is really quite a portable skill once you've learnt at least two dialects, just as learning German and Latin will open most European languages to you.


A few years ago, I learned it to reverse engineer the compression, graphics, and level data formats for an NES game whose levels I wanted to dump.

https://tcrf.net/Proto:M.C._Kids

https://gitlab.com/mcmapper/mcmapper/blob/master/main.c


I'd have thought AVR assembler was a better choice these days - a nice orthogonal 8-bit RISC architecture, and you can use gcc, gas etc. (as well as being able to run your code on an Arduino).


As fun as this may sound, beside nostalgia, are there any real reasons to learn 6502 assembly today?

If you want to learn low level programming there are better and more recent systems out there (avr, arm)


From the article:

"Then why 6502? Why not a useful assembly language, like x86? Well, I don’t think learning x86 is useful. I don’t think you’ll ever have to write assembly language in your day job - this is purely an academic exercise, something to expand your mind and your thinking. 6502 was originally written in a different age, a time when the majority of developers were writing assembly directly, rather than in these new-fangled high-level programming languages.

So, it was designed to be written by humans. More modern assembly languages are meant to written by compilers, so let’s leave it to them. Plus, 6502 is fun. Nobody ever called x86 fun".

ARM and AVR may be better and more recent options but they probably won't be good for introduction purposes.


Actually, I think they are a better introduction to assembly as they are simpler and easier to understand



Oh the nostalgia! This is awesome! And it's the only assembly language I ever learned, as a kid (of course) on an Apple //e in a mostly-unsupervised "computers" class.

Seriuos question though: does anyone here use any assembly language in contemporary work today? If so, what's that like?


This is one of my favorite posts from HN that I stumbled upon last year. Very intuitive and accessible, and worth the read.


I enjoyed using 6502 assembler in my youth. If you want to learn an assembler language that is still in use today take a look at Microchip PIC.


Love the JS emulator, does anyone know of a Windows app that offers the same?


I don't know of this particularly, but the following web page lists a lot of desktop emulators and development environments for the 6502:

http://www.6502.org/tools/emu/

Someone else will have to provide an actual recommendation.


This is wonderful, thank you!


I love you, man! Thanks for posting this.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: