1
votes

I am new in assembler programming and want to get the 6502 to count from 0 to 65536 and want some help to the code. I must use 2 bytes (word), but the problem is that the INC command only increments one byte.

2
Use the ADC instruction.Michael
with 16 bits you can only count to 65535. You need 17 bits to get 65536phuclv
What have you tried? How do you intend to store the value 65536 in two 8-bit bytes since the range of 16 bits is 0-65535?some
Hello. I ment 65535. And i'm gonna use 2 bits. Use the ADC command and that seems to work. But i have problem with the BCS (branch if carryset). The programs dont work after that.Roy Navjord
@RoyNavjord You say you have a problem with the BCS. Could you amend your question to add the code and explain what goes wrong?JeremyP

2 Answers

2
votes

I am new in assembler programming

A hint for the future

Most modern computers (there are only few exceptions) work with bytes. This means: These computers work in a base-256 system.

The same mathematical rules that apply to the decimal system also apply to all other systems - including base-256.

Whenever you want to perform some operation in assembly, you should first think about how the corresponding problem in decimal system looks like and how you would solve it.

to count to 65536 ... I must use 2 bytes (word), but the problem is that the INC command only increments one byte.

The corresponding problem in decimal system is:

I must count from 0 to 100. However, in school I only learned which decimal digit follows another digit (e.g. 6 is followed by 7) but they didn't teach me which 2-digit number follows another 2-digit one (e.g. 86 is followed by 87).

Now let's look at the decimal problem:

To count from 0 to 99, you can use two digits; counting to 100 already requires three digits.

You would probably solve the problem the following way:

  • You start with 000
  • You would count up by one the following way:
    • You would replace the last digit by the following one.
      Example: If the current value is 086, you would replace the 6 by a 7 so you end up in 087.
    • If the last digit is 9, you would replace the 9 by a 0 and replace the middle digit.
      Example: If the number is 079, you would first replace the last digit: 070 and because you replaced the last digit by a 0, you also replace the middle digit: 080
    • If you replace the middle digit by a 0, you also replace the first digit: Performing the steps described above, 099 first becomes 090, then 000, then 100
  • As soon as you performed the last step, your task is done because you reached the value 100.

Assembly language:

Let's look at the steps done in decimal system again and compare it to the steps we have to do in assembly language:

  • Decimal: To count from 0 to 99, you can use two digits; counting to 100 already requires three digits.
    Assembly: Counting from 0 to 65535 can be done using two bytes; 65536 already requires three bytes.
  • Decimal: You start with 000
    Assembly: You have to use some instructions (such as LDA and STA) to ensure that the three (or two) bytes initially have the value 0.
  • You would count up by one the following way:
    • Decimal: You would replace the last digit by the following one.
      Assembly: You use the INC instruction to increment (this means: count up) the last byte.
    • Decimal: If the last digit is 9, you would replace the 9 by a 0 and ...
      Assembly: The INC instruction will count from 255 to 0; this is like counting from 9 to 0 in decimal system. The INC instruction will set the Z flag when it counts from 255 to 0; it will clear the Z flag if it did not do so.
      Using the BNE instruction you can jump to some instruction if the Z flag is not set. This means you can skip some instructions that are only executed if INC counted from 255 to 0. (Or you can jump "backwards" to the start of some loop if you didn't count from 255 to 0 ...)
    • Decimal: ... and replace the middle digit.
      Assembly: You apply the INC instruction to the middle byte.
    • Decimal: If you replace the middle digit by a 0 ...
      Assembly: This means: The INC instruction that you applied to the middle byte has replaced 255 by 0 and therefore set the Z flag!
  • Decimal: As soon as you performed the last step, your task is done because you reached the value 100.
    Assembly: The same is true for counting to 65536 in base-256 system.

Some note:

6502 has three registers: A, X and Y. For this reason, you can also count in the registers (INX, INY ...) instead of counting in memory as long as your largest number is less than 2^24.

2
votes

We know from grade school and base 10 that say

 19
+ 1
====

you use a carry, to carry values into the next power of 10

 1
 19
+ 1
====
  0

9+1 = 0 carry the 1.

This works for all bases. Now also understand zero, there is an implied zero before you started

  0
 19
+ 1
====

as the carry in to that first digit.

 10  
 19
+ 1
====
 20

is what it looks like completed. But what if my paper was so skinny or I wrote my numbers so big I could not fit but one column per page.

the ones column

10  
 9
+1
====
 0

the tens column would need to bring the carry in from the ones column

01  
 1
+0
====
 2

implied zero for the second operand and also recognize this operation has a carry out as well, it is zero so we do not care, then we can take the two operations resulting in a 0 and a 2 and combine them in our head to understand the result to be 20. 19+1 = 20

base 2 or base 16 are no different

  1FFF
+ 0001
=======

the least significant byte, no carry in

 110
  FF
+ 01
=======
  00

then the remaining bytes for as many bytes wide as you desire, need to add the carry in from the prior operation

  11
  1F
+ 00
=======
  20 

giving the result 0x2000 using one byte at a time math.

So depending on how much you want to add per loop you can look at the instructions that do that, paying careful attention to if the carry flag is modified as an output for that operation. Then look for an add operation that adds in that carry flag in order to cascade. Note that it takes four bytes for this in some form the two for the top and the two for the bottom operand, although you may find shortcuts.

likewise if you want to stop at 65535 (We assume you made a typo there), then you need to think about how to do a compare with 0xFFFF a byte at a time and keep looping if both bytes are not the final value.

Or are you actually supposed to count 65536 times from 0x0000 to 0x0000? Same difference except where do you do the loop test? In C would it be a while() or a do...while(), for example.