IF/ELSE in assembly

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
belltone
Posts: 19
Joined: Wed Sep 09, 2015 6:00 pm

IF/ELSE in assembly

Post by belltone »

Hi as easy as possible to write a whole series of IF/ELSE in assembly?

For example I need to check in on our cell numbers in it:

Code: Select all

MY_COLUMN  = $00            ; hex column

MyFunction:
  lda #MY_COLUMN            ; hex column
  cmp #$00                  ; $00 = $00
  bne  MyFunctionDone

  ; your code

  lda #MY_COLUMN            ; hex column
  cmp #$01                  ; $00 = $01
  bne  MyFunctionDone

  ; your code

  lda #MY_COLUMN            ; hex column
  cmp #$02                  ; $00 = $02
  bne  MyFunctionDone

  ; your code
        
  lda #MY_COLUMN            ; hex column
  cmp #$03                  ; $00 = $03
  bne  MyFunctionDone       
MyFunctionDone:
How it can be made easier in my case?
How to write a nested loop?

I took examples on page Levi D. Smith: https://speakerdeck.com/gatechgrad/prog ... ent-system
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: IF/ELSE in assembly

Post by tokumaru »

If a test fails, don't jump to the end, jump to the next test. If a test succeeds, then you do whatever is related to that condition and then jump to the end, so the other tests are not performed.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: IF/ELSE in assembly

Post by Dwedit »

If/Else usually looks like this:

Calculate condition codes
Conditional jump to Else label if the condition is false
Code here if true
JMP endif_label
else_label:
Code here if false
endif_label:


Example:
;if a > 10
; ...
;else
; ...
;end if
CMP #10
BCC else_label
... code here ...
jmp endif_label
else_label:
... code here ...
endif_label:

This is the extremely formal version, where the condition always jumps ahead if false, so the If condition comes first, and there is always an unconditional jump to the endif label. If there is no Else condition, then the Else label collapses into the same thing as the endif label, and the jump to end if becomes a pointless jump to the next instruction.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: IF/ELSE in assembly

Post by Garth »

There are different ways to handle this. But to start, note that there's an automatic, implied, built-in compare-to-0 in every instructions that loads or affects A, X, or Y; so there's no need for CMP #0 after LDA. Also, if it's a chain of comparisons against successive numbers, you can increment or decrement the number each time (instead of re-loading it) and take advantage of the automatic, implied compare-to-0 in that instruction. Below, I used DEC A (decrement accumulator), or DEA; but if you have only the NMOS 6502 and not the CMOS, you won't have that instruction, but you could load the number initially into X or Y instead and then use DEX or DEY.

Code: Select all

MyFunction:
    lda  #MY_COLUMN
    bne  1$

    ; your code

1$: DEC  A
    bne  2$

    ; your code

2$: DEC  A 
    bne  3$

    ; your code
       
3$: DEC  A
    BNE  MyFunctionDone

    ; your code
      
MyFunctionDone:
(You may need to change the label system to work with whatever assembler you're using. Also, I don't know what you have at the end of each "your code" section, regarding where it goes when it's done.) I have a bunch of these in section 20 ("Tips For Programming the 65(c)02") of the 6502 primer.

Another thing you can do for successive numbers is use a table. This runs faster and saves memory if there are quite a few choices. If you can't confine the numbers to even numbers, like if you really need 0, 1, 2, and 3, then load it, double it with ASL, transfer it to X, and use it for indexing in a table of addresses. (The doubling is because each address in the table takes two bytes.) What you do need to be careful of in this case is that if the input is ever something unexpected, you will index outside the table and probably get garbage as an address to jump to, and you'll get a crash!

I like to use structure macros, per my article at http://wilsonminesco.com/StructureMacros/ . A CASE structure would be good for a situation where the numbers are somewhat random, like if you wanted to have special handling for certain characters like <CR>, <LF>, and <BS>, and let all the others get handled a default way. So you could have for example:

Code: Select all

       CASE  ACCUM        ; Test the accumulator against the following cases.
           CASE_OF  $0A   ; If it has the linefeed character,
              <actions>   ; execute these instructions,
              <actions>
           END_OF         ; then jump to the first instruction after END_CASE.


           CASE_OF  $0D   ; If it has the carriage-return character,
              <actions>   ; execute these instructions,
              <actions>
           END_OF         ; then jump to the first instruction after END_CASE.


           CASE_OF  $08   ; If it has the backspace character,
              <actions>   ; execute these instructions,
              <actions>
           END_OF         ; then jump to the first instruction after END_CASE.


           <actions>      ; If the character is anything else, do these actions
           <actions>      ; to feed it to the display as display data.
       END_CASE
As you might expect, what it assembles is a series of CMP #__, BNE instructions, plus the jumps to the first instruction after END_CASE.
http://WilsonMinesCo.com/ lots of 6502 resources
Post Reply