6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 16, 2024 8:51 pm

All times are UTC




Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Thu Oct 14, 2021 4:13 am 
Offline

Joined: Sat Jun 05, 2021 6:56 am
Posts: 19
So, I've got the bit of code I've been working on mostly cleaned up and reorganized to flow more efficiently and logically, but there's still one bit that has me scratching my head.

Perhaps it's a bit of leftover cruft that was never tidied up (wouldn't be surprised, given the inefficient use of code and inconsistencies I'd found along the way).

Here goes:

Code:
LB_E12B   JSR   LB_FA63
      LDA   $B9
      ASL
      BCC   LB_E15E
      LDY   $BD
      CPY   #$0B
      BNE   LB_E15E
      LDX   #$00
      STX   $0C69
      AND   #$06      ???
      BEQ   LB_E159      ???
                LDX #$F0
                STX $0C6B
                LDX #$FF
      STX   $0C6C
      CMP   #$02      ???
      BEQ   LB_E159      ???
      LDX   #$00
      STX   $0C6B
      STX   $0C6D
      STX   $0C6F
LB_E159   JSR   LB_F0F6
      JMP   LB_E12B
LB_E15E   ASL
               BCC ...


The ONLY values that are stored in $B9 are: 00, 14, 4C, A4, AD, or AE.

I can't see how any of these values, if shifted left, would meet either conditional, or am I missing something?


Last edited by Meterman58761 on Thu Oct 14, 2021 10:57 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 14, 2021 6:34 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
There's something fishy about that code, especially the LDX #$F0FF, which suggests to me that your disassembler is getting out of sync. That's not the only instruction, but it sticks out like a sore thumb to me. Can you share the hex? It's possible that we can see why your disassembler apparently got confused.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 14, 2021 6:37 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
BillG wrote:
Code:
00 14 4C A4 AD AE   Your numbers
00 28 98 48 5A 5C   shifted left
00 00 00 00 02 04   and anded with 6


AD and AE will fall through the first BEQ

AE will fall through the second.


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 14, 2021 11:00 pm 
Offline

Joined: Sat Jun 05, 2021 6:56 am
Posts: 19
Barry: I grabbed the wrong bit of code before posting (it was a too-quick copy / clean / paste from the original 68xx code). I made a correction that should help.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 15, 2021 5:32 am 
Offline

Joined: Sat Jun 05, 2021 6:56 am
Posts: 19
I guess I'm a bit confused on the proper use of AND in conjunction with BEQ / BNE versus in conjunction with CMP.

So, if I do the AND with 6, leaving 0, then the Z flag goes up, at which point BEQ kicks in, right?

Whereas my thinking of BEQ has centered on whether the remainder after being ANDed is equal to 6 or not...


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 15, 2021 6:33 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Meterman58761 wrote:
I guess I'm a bit confused on the proper use of AND in conjunction with BEQ / BNE versus in conjunction with CMP.

CMP does a subtraction, without regard to the carry flag, nor keeping the result. It also does not set the V flag; so it cannot be used for signed comparisons. All it does is modify the N, Z, and C flags. If the result of the subtraction is 0, the Z flag gets set.

Quote:
So, if I do the AND with 6, leaving 0, then the Z flag goes up, at which point BEQ kicks in, right?

AND is a bitwise AND. AND #6, ie, AND %00000110, zeroes six of the eight bits, every accumulator bit except bits 1 and 2, and sets the Z flag if both those remaining bits are 0; otherwise it clears it. It also also transfers the msb to the N flag; and in this case, since you ANDed with a number that has 0 in the msb, N will be cleared, regardless of what number you started with.

Quote:
Whereas my thinking of BEQ has centered on whether the remainder after being ANDed is equal to 6 or not...

No; 6, bitwise-ANDed with 6, still results in 6, ie 00000110 in binary, which is definitely not zero, so the Z flag will not be set.

I strongly recommend you get the "Programming the 65816—Including the 6502, 65C02 and 65802" 6502/65816 programmer's manual by David Eyes and Ron Lichty. This is definitely the best 65xx programming manual available, and a must-have for every 65xx programmer! It starts with the basics, followed by architecture, the CMOS 65c02's many improvements over the original NMOS 6502 including added instructions and addressing modes and fixing the NMOS's bugs and quirks, and then the natural progression to the 65816; a thorough tutorial, writing applications, then very detailed and diagrammed information on all 34 addressing modes, at least a page of very detailed description for each instruction, with info on every addressing mode available for that instruction, then instruction lists, tables, and groups, of all 255 active op codes, plus more. 469 pages. From Western Design Center. (.pdf) Note: There were many problems with the earlier .pdf version that were not in the original paper manual; but in late March 2015, WDC scanned and OCR'ed the paper manual and posted the new, repaired .pdf.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 15, 2021 8:45 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10981
Location: England
From this angle it does look a little as if BEQ could have been named BZS: it's a test of the Z flag. We can think of BEQ as testing for zero - but we do need to know that CMP does a silent subtraction. It's a great instruction set, but I see now how it has some nooks and crannies, and takes a little getting used to.

It's very valuable to have explanations from someone who is learning the ropes. It can be difficult to see something with fresh eyes when you're very familiar with it.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 15, 2021 6:42 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
BigEd wrote:
From this angle it does look a little as if BEQ could have been named BZS: it's a test of the Z flag. We can think of BEQ as testing for zero - but we do need to know that CMP does a silent subtraction.

Some (many?) assemblers allow you to define aliases for the standard mnemonics.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 16, 2021 12:55 am 
Offline

Joined: Sat Jun 05, 2021 6:56 am
Posts: 19
There we go. Looks like that was the last bit that needed cleaning.

Now that I got the last of the spaghetti picked out and the one 'test byte' ($B9) documented in regards to which conditionals are tripped by which values, I can focus on the interrupt section.

I guess from seeing CMP and BEQ / BNE paired many times through the years, I had a flawed understanding of exactly what those specific opcodes do.

I never really realized that CMP does a silent subtraction (just like BIT's 'silent' AND), but that now explains why I see a few CMP and BPL / BMI pairs in the code.

I guess that one could theoretically set up CMP to work with BCC / BCS or even BVC / BVS, right? (although I don't see where I would need to).

I think BZS would be too easy to confuse with BCS or BVS. Perhaps it should be BEZ / BNZ. Ah well! I (re)learned something, and that's what counts!


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 16, 2021 1:05 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Meterman58761 wrote:
I guess that one could theoretically set up CMP to work with BCC / BCS or even BVC / BVS, right? (although I don't see where I would need to).

Again, CMP does not affect the V flag.

Quote:
I think BZS would be too easy to confuse with BCS or BVS. Perhaps it should be BEZ / BNZ. Ah well! I (re)learned something, and that's what counts!

BZS (Branch if Zero flag Set) should not be confusable with anything regarding the Carry or oVerflow flags. The flags are separate for a reason.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 17, 2021 5:53 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Perhaps I should have added a part from the "Programming tips" page of the 6502 primer at http://wilsonminesco.com/6502primer/PgmTips.html, from just after the heading "Avoid commonly wasted instructions:" almost halfway down the page:

    1. An automatic compare-to-zero instruction is built into the following 65c02 instructions: LDA, LDX, LDY, INC, INX, INY, DEC, DEX, DEY, INA, DEA, AND, ORA, EOR, ASL, LSR, ROL, ROR, PLA, PLX, PLY, SBC, ADC, TAX, TXA, TAY, TYA, and TSX. This means that, for example, a CMP #0 after an LDA is redundant, a wasted instruction. A kitten somewhere dies every time you do that! :lol: The only time a 65c02 (CMOS) needs a compare-to-zero instruction after one of these is if you want to compare a register that was not involved in the previous instruction; for example,
    Code:
            DEY
            CPX  #0

    (Note the Y and the X are not the same register.) If you can spare a register to which you can transfer the one you want to test, you can save a byte with the transfer instead of a compare instruction. The example above, if the contents of A don't need to be kept, could be changed to:
    Code:
            DEY
            TXA

    and then you can branch on the N or Z flag which tell if X was negative or zero. The TXA isn't any faster (both TXA and CPX# take two clocks); but TXA takes only one byte, whereas the CPX #0 takes two bytes.

    The NMOS 6502 did have a bug in that the flags weren't always correct after a decimal-mode operation like ADC; so then you might have to follow it with the CMP #0 to get the N and Z flags right. It's best to just use the CMOS processor for any new projects.

    2. Similarly, if you want a compare to $80 strictly for branching on the N flag results, you can omit the compare-to-$80 instruction and branch on the opposite state of the N flag. For example
    Code:
            DEA            ; (same thing as DEC A)
            CMP  #$80
            BMI  <label>

    can be replaced with
    Code:
            DEA            ; (same thing as DEC A)
            BPL  <label>

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 17, 2021 6:25 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8491
Location: Midwestern USA
BigEd wrote:
From this angle it does look a little as if BEQ could have been named BZS...

There are historical reasons why BEQ is BEQ and not something else—also true for the other branching instructions.

Recall that the 6502's grandfather is the MC6800. MOS Technology believed that adopting most of the 6800 assembly language would encourage engineers to adopt the 6502, since it would be relatively easy to port 6800 programs. Since the 6800 used BEQ, BNE, etc., for branching mnemonics, the 6502 inherited those instructions, along many others. Of course, there were quite a few 6800 instructions that were deleted for cost-reduction reasons (RIP BSR)...only for a few to reappear in the 65C02 and 65C816.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 17, 2021 7:32 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8491
Location: Midwestern USA
Meterman58761 wrote:
I never really realized that CMP does a silent subtraction (just like BIT's 'silent' AND)...

As Garth mentioned above, all of this is described in great detail in the Lichty & Eyes manual, which we highly recommend you read. The 6502 family is probably the most documented microprocessor family of all time, so there really isn't any excuse for not having plenty of reference materials on hand as you learn the assembly language.

Quote:
but that now explains why I see a few CMP and BPL / BMI pairs in the code.

CMP followed by BPL or BMI can get the unwary beginning programmer into trouble. BPL and BMI test the state of the N flag in the status register (SR). As Garth noted, comparison is a subtraction that discards the difference and only affects SR, specifically the C, N and Z flags. The effect on N is the result of signed subtraction, which won't always result in what you might expect.

For example, the following code doesn't work the way you'd think it would:

Code:
         lda #$00
         cmp #$FF
         bmi less_than

The branch to LESS_THAN will not be taken, even though $00 appears to be "lower" than $FF.

Quote:
I guess that one could theoretically set up CMP to work with BCC / BCS or even BVC / BVS, right? (although I don't see where I would need to).

Again, you need to do some reading. CMP doesn't "work" with the branch instructions. What CMP does is condition SR flags. In some cases, CMP may not be followed by a branch, as it is the effect on the flags that was what prompted the use of CMP. For example, an addition, subtraction or some other operation that is not a branch may follow CMP, taking advantage of how CMP affected carry.

As for use of BCC and BCS, those are frequently employed to determine if a compared value is the same as, higher or lower than the comparison value, since there is no specific "greater than" or "lesser than" branch instruction. For example, here are two frequently-used comparison sequences involving both C and Z:

Code:
         lda value1
         cmp value2
         bcc lower             ;value1 < value2
;
         bne higher            ;value1 > value2

or...

Code:
         lda value1
         cmp value2
         bcs same_greater      ;value1 >= value2

Again, carry results from the subtraction of CMP.

CMP, also CPX and CPY, won't affect the V flag, so use of BVC or BVS following a comparison would be ambiguous at best. Those branches are primarily of value when carrying out signed arithmetic, or when using BIT to test flags, since BITing a memory location will copy bits 6 and 7 into V and N, respectively.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 17, 2021 8:27 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10981
Location: England
(Edit: see downthread. This tutorial may be mistaken about signed values.)

I recommend this document on branches, if you really want to understand deeply:
http://6502.org/tutorials/compare_instructions.html

It notes there that the C flag is useful when the inputs are considered unsigned values, and the N flag is useful when they are considered signed values.


Last edited by BigEd on Mon Oct 18, 2021 4:33 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 18, 2021 4:00 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8491
Location: Midwestern USA
BigEd wrote:
I recommend this document on branches, if you really want to understand deeply:
http://6502.org/tutorials/compare_instructions.html

It notes there that the C flag is useful when the inputs are considered unsigned values, and the N flag is useful when they are considered signed values.

Yes, the tutorial does say that, and I'll return to that in a few sentences, but what I was pointing out was the use of BPL or BMI following a CMP can take a programmer down a dirt road. The implied subtraction carried out by CMP is always unsigned. My previous example of CoMParing $FF to $00 illustrates this.

Regarding the tutorial, its recommendation to use BPL and BMI in signed comparisons is incorrect. Rather than have anyone take my word for it, I'll quote something from the Eyes & Lichty manual:


    There are also no branch instructions available for signed comparisons, other than equal and not equal.

(Page 151, emphasis added.)

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: