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.)
What i learned from the 6502 was the use of pointers through the indirect addressing, later when I learned C they became vey easy.
The 6502 supports function calls easily: JSR/PHA/PLA/RTS
(Better even than some modern microcontrollers…)
The 6502 stack is pretty much a toy for a language like C or Pascal, and you definitely need to use a non-hardware stack for actual variables and stuff, probably even return addresses.
(I never ran out of 6502 stack programming in assembly, and I wrote a LOT of it, back in the day).
They still do, only in Linux/BSD land they do not.
After all, people have to bring bread back home.
Visual studio full version is not free, but you can easily build (compile, link, run) everything for zero dollars. (Not even a picodollar.)
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?
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!)
I later learned IBM 370 assembler (why not have the CompSci's assembler class on a mainframe) and 8086/88. I hated both. They felt wrong compared to the 6502/6509. Although 8086 assembler did help my grade in the graphics class.
Assembler is great to learn because it teaches you what the final form of your program is.
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!
6502 isn't dead, it has even been relaunched:
http://www.h-online.com/open/news/item/Relaunched-the-6502-m...
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.
From WDC's homepage:
"Annual volumes in the hundreds (100’s) of millions of units keep adding in a significant way to the estimated shipped volumes of five (5) to ten (10) billion units. "
Also, FPGAs are typically configured with an HDL, which can be likened more to C than assembler.
Yes currently, but price depends on demand. On the other side, if FPGAs remain expensive then Assembler could become even more important to put as much code as possible into an fpga.
> can be likened more to C than assembler.
For that reason I mentioned the word Assembler in quotes. Btw VHDL is much more like Ada than C while Verilog is different from both.
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.)
With the 32x32 display they could even do some simple graphics to stretch themselves :)
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.
http://www.youtube.com/watch?v=Gg8Dtod83qA
It's so much fun developing in 6502 assembler again!!!
Game looks great, btw!
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?
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!
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?
* 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.
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.]
0xfe is a random number - a new random byte is generated on every instruction.
0xff contains the ASCII code of the last key pressed.
My simulator is adapted from the one at http://6502asm.com/beta/index.html - that has a help screen with some more info. I mostly cleaned up the (atrocious) JavaScript and added a memory monitor and disassembler (and implemented a few instructions they'd left out).
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.
I remember writing programs that wouldn't have fitted in memory if we'd used things like "STORE_ADDRESS" instead of "STA". The assembler would have had to have been more complex in order to process instructions that were of variable length, instead of the opcodes being a predictable 3 letters.
I've written assembler by hand - sheets and sheets of it - because there wasn't a decent editor on the machine I was writing for. These were the days when you were writing code for the machine, and not for the people who would maintain it afterwards. The structure of the code had to be clear, and the comments were as much for yourself as anyone else, but the opcode names were a complete non-consideration. If you didn't know them, you couldn't program anyway.
1) learning something new you might as well have something easier to learn 2) just becasue historicaly you had to use abreviations is not a handicap you have to impose upon yourself thesedays - especialy if your learning it from scratch and for educational aspects. 3) Sure you can use short TLA's instead of a longer version but for ease of reading and learning then something alot cleareer for the human without that over-comprimise you had with memory of computers is a artificial limitation. 4) realy not hard to run a substitution script to conver long to short and vice a versa - sed anyone!
We have all done assembly by hand and hand converted it, the compiler was a luxury for some back then and there small memory machines and even then you were not limited by the official shortcode versions of TLA's.
Thing is with hand converting is that you write something not maintainable on many levels, but as you said, you bent towards those lmitations as you had not alot of choice.
So if you want on say a Z80 write RETURN or the offical mnenoic of RET or go real hard code and just write C9 (using this example as my personal memory space seemed to of kept that one alive) then it was your choice. When you went to code it was C9h so converting RETURN or RET was something you did.
Least only op code that was standard across CPU's was NOP or "NO OPERATION" aka do nothing or 00h or 0 or 00000000, that was kinda portable and used by many for funky double-entry code padding etc. Though that was due to memory limitations and scary stuff to maintain, yet fun and rewarding to code. Apple early OS used that approach alot due to memory limitatons.
Heck of memory was such a limitation back then - explain COBOL becasue I can't, sadly still remember that as well :|.
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... 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.
"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" yes and no, were both right. ARM looked at a 16bit replacement for the 6502 and found the options of the 68000 not having the performance they wanted. They went to America and checked out the work on the replacement for the 6502 and concluded that they could just make there own CPU and so they did.
Had the replacement for the 6502 not been a one man team then history would be different now.
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.
Incidentally, I wrote a simple 6502 assembler back in the days, and I took the opportunity to invent my own notation, just for fun. I became quite adept at reading and writing it, and standard notation felt very verbose after a while.
Here is, in standard notation, a program that copies 256 bytes from ORIGIN to DEST.
LDY #$00
LOOP LDA ORIGIN,Y
STA DEST,Y
INY
BNE LOOP
RTS
Here is the same program in my notation (yes, all on one line. I used a space character to delimit instructions). Y<0 LOOP: A<(ORIGIN,Y) A>(DEST,Y) Y+ #LOOP ]Fixed width is easier to process and not necasaryly to write. Remember it is about learning a assembler here - not pandaring towards limited computer memory and processing approaches of the time. THAT is a seprate issue and on that note thanks for the mod down point ;|.