I'm trying to write a while loop in assembly with a 6502 processor and I cannot figure out how to write the hexadecimal code. I've seen examples written using the shorthand where there is a label for where the loop should begin and end but I do not see anything for the actual hex code.
The two codes I see being useful are:
Here's a place for you to start. The page features a cross-assembler that you can run on your PC. That could be a good dev platform for you.
Before doing anything, you have to understand the theory of operation of the 6502. Then you have to understand the software-development process that includes:
-- preparing a "source file," so called,
of symbolic instructions that you
call "shorthand"
-- using an
assembler, translating that source
file into machine instructions that
the 6502 understands
-- loading the
translation into the 6502
-- telling
the 6502 to execute the translated
machine instructions
Your example program tries to copy LEN
memory bytes from SRC
to DST
.
You format it like this:
LDX #0 ; Start with the first byte
_LOOP LDA SRC,X ; load a byte from SRC into the A register
STA DST,X ; store that byte into DST
INX ; bump the index register to point to the next SRC and DST locations
CPX #LEN ; have we moved LEN characters?
BNE _LOOP ; if not, go move the next one
After you have added more statement lines (like END
, for example); and after you have defined SRC
, DST
, and LEN
, you save the whole thing in a file called, let's say, cploop.txt
.
Then you tell the assembler to translate it. The assembler comes out with a file of binary 6502 machine code that cam be represented as the hex bytes you're talking about.
You feed that file of machine code to the simulated 6502. Then you somehow tell the 6502 to execute the operations that the machine code embodies.
Here's an example showing the correspondence between assembly (what you call "shorthand") and machine code. First, here's the assembly code for the algorithm, with some parameters abstracted away:
* = 4000 ; This is the address where our program will be stored
LDX #len
loop LDA src,X
STA dest,X
DEX
BNE loop
Of course, you can't turn that directly into machine code. You also need to fill in the values of len
, src
and dest
:
src = $1234
dest = $5678
len = 10
The thing to understand about the loop
name is that just like src
is assigned the value $1234
, loop
will be assigned the address of the instruction after it. So in this case, since LDX #len
takes up 2 bytes (as I'll show you shortly), loop
is set to $4000 + 2 = $4002
. This is done automatically by the assembler, but of course you could do all this on paper as well.
So what is the 6502 machine code for the above assembly program?
A2 0A
BD 34 12
9D 78 56
CA
D0 F7
How do I know this? Well, I've just pasted the above program into the online 6502 assembler at http://www.masswerk.at/6502/assembler.html. It even shows you the detailed mapping between assembly and machine code:
4000 LDX #LEN A2 0A
4002 LOOP LDA SRC,X BD 34 12
4005 STA DEST,X 9D 78 56
4008 DEX CA
4009 BNE LOOP D0 F7
400B
Note how the actual value of LOOP
is not even used to compute the machine code for BNE LOOP
, only its relative address compared to the BNE
instruction itself: F7
is -9, and the difference between $400B
and $4002
is -9!
So if you were to do this by hand, you'd just translate everything else into machine code, then when you get to a jump, you compute the difference between the next instruction's starting address and the jump destination's address. It should be negative for backwards jumps and positive for forward jumps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With