
Get Started with 6502 Assembly Programming on Atari Lynx - ikromin
https://atarigamer.com/articles/get-started-with-6502-assembly-programming-on-atari-lynx
======
nategri
Learning to write 6502 was a formative experience for me as a programmer and I
strongly recommend it as a pedagogical exercise if nothing else. The
instruction set is tiny, and easy to grapple with, but after learning it
you'll get an intuitive grasp of, for instance, "why the C programming
language is the way it is."

So all that remains is to pick a platform! And there's no shortage of them.
Glad to see Lynx is yet another participant in the vibrant 6502 homebrew
community.

~~~
verisimilitudes
>The instruction set is tiny, and easy to grapple with, but after learning it
you'll get an intuitive grasp of, for instance, "why the C programming
language is the way it is."

If you want that, you should learn the PDP-11 instruction set, which is
actually why the C language is the way it is. In particular, C is rather
uniquely unsuited for segmented memory models, which many 6502 systems have,
whereas other languages with lower-level features or accommodations can easily
function under such a memory model, because they were designed with it in mind
instead of solely for the PDP-11.

On that note, C isn't actually a low-level language and I'm aware the 6502 is
an example of an instruction set it maps very poorly to, compared to how a
machine code programmer would approach it, so I'm curious why you made this
relationship, since it's rather tenuous.

~~~
duskwuff
> In particular, C is rather uniquely unsuited for segmented memory models

C was often used to program 16-bit x86 systems, and it handled that well
enough.

A more relevant limitation of the 6502, however, is its stack. The 6502 stack
is limited to a single page of 256 bytes, and there is no stack-relative
addressing mode. This makes a C-style stack difficult to implement -- most C
implementations for the 6502 implement a secondary data stack in main memory.

~~~
burfog
A good compiler would focus optimization efforts on removing variables from
the stack. It would probably just reject programs that get silly with deep
recursion.

For example, if the compiler can prove that a function never gets more than
one active stack frame (no recursion) then the local variables don't need to
be on a stack. They can be in the data section. If the compiler can prove this
for two functions together, such that they will never both have active stack
frames, then the variables can reside in the same memory. Going beyond this,
partial sharing is possible. If function X calls function Y, the variables of
function Y can reside in the locations of many of the variables of function X.
It is only the variables of function X that must survive the call to Y that
would need distinct memory locations.

Inlining can help too. That gets rid of the need to push a return address and
so on.

~~~
duskwuff
I'm not sure that's a valid set of optimizations. It's certainly incompatible
with a compile-then-link workflow involving multiple object files, as there's
no way to safely allocate local variables across modules. Nor is this approach
compatible with function pointers!

~~~
burfog
I know that moving stack variables to the data section is in fact an
optimization that is in use by commercial compilers. It works fine with
function pointers. There are two possible answers to the problem of a compile-
then-link workflow involving multiple object files.

The first is that the optimization can be limited to within one file. Calls
going between source files can sometimes limit the optimization opportunity
because it may become impossible to prove that there is no mutual recursion.
Functions that may be involved in recursion can not be optimized in this way.
One might add a #pragma to override the compiler's determination of safety.

The second possible answer is to have the link phase do the real compiling.
The supposed compile phase just preprocesses and verifies syntax.

Function pointers certainly liven things up. Suppose the function pointer of
type *X is used to call a function of type X, which then exclusively calls
functions of type Y. If we know that none of those type Y functions end up
calling any type X functions, then that first-mentioned function of type X
will not get more than one stack frame. It is thus safe to optimize with that
assumption.

------
zellyn
Here's an in-browser 6502 tutorial with simulator:
[https://skilldrick.github.io/easy6502/](https://skilldrick.github.io/easy6502/)

Of course, you can pick the system/context you want to learn in: many 8-bit
computers used 6502 chips. For example, this book is well-regarded for those
with Apple II nostalgia:
[https://archive.org/details/AssemblyLinesCompleteWagner](https://archive.org/details/AssemblyLinesCompleteWagner)

I'm sure there are tons of NES-targeted tutorials too.

~~~
dillonmckay
Anybody have good NES tutorials and also a link for a way to put it on a cart
(sd or whatever)?

Also, are their free or paid-for asset libraries?

Thanks in advance!

~~~
nwallin
nesdev.com is a treasure trove of information.

To put it on a cart, you'll use RetroUSB PowerPak or Everdrive N8.

Don't know about assets.

------
kgwxd
Atari 2600 programming is 6502 too, you can play with it right in the browser:
[http://8bitworkshop.com/v3.3.0/?=&file=examples%2Fcomplexsce...](http://8bitworkshop.com/v3.3.0/?=&file=examples%2Fcomplexscene2&platform=vcs)

~~~
tom_
My suggestion: anybody thinking of getting started with 6502 will probably
have more fun with the Atari Lynx.

~~~
Malic
Or the C64 might be a good choice too.

Jumping into "no-framebuffer/racing-the-beam" 6502 programming on the Atari
2600 for the uninitiated is just ... cruel.

~~~
NikkiA
I'd recommend the BBC Micro, since we're not talking about the 1980s and
geographical limitations of the market, the BBC has a nice basic that includes
a built-in assembler, has a text UI that is more pleasant on the eyes than
most 8bits, has the sideways rom system to make it possible to add a debugger
and other niceties, and has a simple easy-to-understand disk filing system.

------
burfog
The closest modern equivalent to those old 8-bit computers is the TI-84 Plus
CE calculator. It has a legit (no hacks) way to load binary executables. It
goes for about $100. Like many old 8-bit computers, it comes with BASIC and an
almost-ASCII character set. The screen is 320x240, just a tad bigger than
those old 8-bit home computers usually had, though with 16-bit color. There is
a USB port. You get a bit more RAM, with about 64 KiB of about 256 KiB
available for your program. The screen is at a fixed address you can write to.

The C compiler is fascinating. There is a uint24_t which maps to an unsigned
int. This is because the EZ80 CPU is capable of ganging three 8-bit registers
together to handle 24-bit data. Pointers are also 24-bit. The "short" and
"long" types are of normal size, 16-bit and 32-bit. There is no alignment or
padding. Serious stuff needs to be in assembly. The C compiler doesn't
optimize very well.

So that is 3 programming languages on a $100 device that happens to be useful
for all sorts of normal school classes. The calculator is fine for the SAT,
ACT, AP Statistics, AP Calculus, and now even the AP sciences.

~~~
aidenn0
I remember having a printout of the tasm tables for x80 so I could type hex
machine-code into my TI-83 (it could load hex programs as binaries). I don't
recommend that approach, but I certainly learned a lot.

------
vga805
I understand the font choice, but you might want to reconsider. It's not easy
to read.

------
jcmeyrignac
There is a typo in the chapter "Important commands that don't exist!".

NEG is described as:

    
    
      EOR #255 (XOR/Flip bits)
      SEC (Clear carry)
      ADD #1  (add 1)
    

Of course, it's:

    
    
      EOR #255 (XOR/Flip bits)
      CLC (Clear carry)
      ADC #1  (add 1 with carry 0)
    

or:

    
    
      EOR #255 (XOR/Flip bits)
      SEC (Set carry)
      ADC #0  (add 0 with carry 1)

~~~
jdswain
There is an INC A instruction on the 65C02 and 65816, so this is better if you
have anything newer than the NMOS 6502:

    
    
      EOR #255   ; Invert
      INC A      ; Add 1
    

It looks like the Lynx has a 65SC02 which is a 65C02 without the bit
manipulation instructions, so it should have the INC A instruction.

------
rbanffy
I wonder why people say it's a 16-bit console if it's based on the 65SC02. The
65816 and 802 were 16 bit, but the SC02, AFAIK, was not.

~~~
glhaynes
It had a 16-bit graphics processor, which arguably was a lot more important
for its software than whether the CPU was 16-bit.

See also the TurboGrafx-16 console, which had a similar arrangement: an 8-bit
6502-descendent and a 16-bit graphics chip. It got a lot of flak for being
“fake 16-bit”. I think the Lynx was better able to get away with it because it
was on such a different level than other handhelds of the time (besides maybe
the expensive portable version of the TG-16!), whereas the TG-16 had to go up
against the 68000-based Sega Genesis.

~~~
rbanffy
So I guess I'll say my Chromebook has 2 + 160 + 20 + 2 or about 184 cores. I'm
counting the integrated GPU, of course.

------
FPGAhacker
Wow. I bought a Lynx with my first paycheck from my first “real” job when I
was 15. I played California Games _a lot._

------
LIV2
Nice!

Another good resource is forum.6502.org as there are plenty of 6502 experts
there that have built their own 6502 machines for a hobby

~~~
tenebrisalietum
Including one made out of discrete components.
[https://monster6502.com/](https://monster6502.com/)

