Author Topic: Branching on the carry flag (680x MPU)  (Read 844 times)

0 Members and 1 Guest are viewing this topic.

Offline metertech58761Topic starter

  • Regular Contributor
  • *
  • Posts: 154
  • Country: us
Branching on the carry flag (680x MPU)
« on: March 30, 2023, 01:29:28 am »
From a 65xx perspective, I'm somewhat familiar with the stated intent of the BCC / BCS opcodes, where you add or subtract, then use these opcodes to proceed based on the state of the carry flag.

I'm also familiar with the trick of shifting a value bit by bit then using these two opcodes to direct program flow, as it was used quite a bit in some other code I recently analyzed (and IMHO, BIT / Z flag branching would be a cleaner approach).

Anyway, my question. Looking in the 6801 programming manual, it seems that BCS is also known as BLO (Branch if Lower) and conversely, BCC is also known as BHS (Branch if Higher or Same).

As I flail about in the darkness trying to undertstand this other bit of code, I'm seeing some seemingly out of place BCC / BCS opcodes.

How can I be sure if when I see the BCC / BCS opcodes in this code dump, that I'm not actually looking at BHS / BLO? Some of these are immediately preceded by LD_ statements, for example.
 

Offline gslick

  • Frequent Contributor
  • **
  • Posts: 580
  • Country: us
Re: Branching on the carry flag (680x MPU)
« Reply #1 on: March 30, 2023, 02:54:10 am »
It probably only makes sense to consider the instructions to be BLO or BHS if they occur shortly after compare (CBA, CMP, CPX) or subtract (SBA, SBC, SUB, SUBD) instructions.

The load instructions (LDA, LDD, LDS, LDX) don't affect the carry flag, so you would have to look back further to the the most recent comparison, arithmetic, or shift/rotate instructions. Most other instructions don't modify the carry flag, but you really need to check the reference manual for each instruction to be sure.
 

Offline srb1954

  • Super Contributor
  • ***
  • Posts: 1091
  • Country: nz
  • Retired Electronics Design Engineer
Re: Branching on the carry flag (680x MPU)
« Reply #2 on: March 30, 2023, 04:30:37 am »
From a 65xx perspective, I'm somewhat familiar with the stated intent of the BCC / BCS opcodes, where you add or subtract, then use these opcodes to proceed based on the state of the carry flag.

I'm also familiar with the trick of shifting a value bit by bit then using these two opcodes to direct program flow, as it was used quite a bit in some other code I recently analyzed (and IMHO, BIT / Z flag branching would be a cleaner approach).
Check the BEQ (Branch on equal to zero) and BNE (branch on not equal to zero) for your ZERO tests.

BPL (branch on plus) and BMI (branch on minus) are also useful for checking whether the MSB is set or not. A lot of 6800 peripheral chips store their ready/busy status in the MSB of their status registers so the BPL/BMI can be very useful in checking the chip status.
Quote
Anyway, my question. Looking in the 6801 programming manual, it seems that BCS is also known as BLO (Branch if Lower) and conversely, BCC is also known as BHS (Branch if Higher or Same).

As I flail about in the darkness trying to undertstand this other bit of code, I'm seeing some seemingly out of place BCC / BCS opcodes.

How can I be sure if when I see the BCC / BCS opcodes in this code dump, that I'm not actually looking at BHS / BLO? Some of these are immediately preceded by LD_ statements, for example.
They are the same opcode - it is just a different way of interpreting the status flags resulting from a preceding operation.
 

Offline Circlotron

  • Super Contributor
  • ***
  • Posts: 3180
  • Country: au
Re: Branching on the carry flag (680x MPU)
« Reply #3 on: March 30, 2023, 05:20:34 am »
BPL (branch on plus) and BMI (branch on minus) are also useful for checking whether the MSB is set or not. A lot of 6800 peripheral chips store their ready/busy status in the MSB of their status registers so the BPL/BMI can be very useful in checking the chip status.
Don't be like me and use BMI to check for a possible underflow after an unsigned subtraction.  :palm:
 

Offline metertech58761Topic starter

  • Regular Contributor
  • *
  • Posts: 154
  • Country: us
Re: Branching on the carry flag (680x MPU)
« Reply #4 on: March 30, 2023, 06:25:01 am »
gslick: You just reminded me that CMP is basically a subtract operation, so the carry flag does come into play there, so thank you.

So if an ASL was done to kick bit 7 into the carry flag, then the accumulator gets overwritten with a new value, the carry flag should still ride on through with no change, right?

srb1954: That's what I meant - in the other code, I ended up changing out the LSR / BCC or BCS with BIT / BEQ or BNE as appropriate. Went a long way towards clarifying that code...

In this case, the only 68xx support chips I'm dealing with are the 6821 and 6840. Although the control registers are written to fairly frequently in this code, there doesn't seem to be much if any polling of the status registers. Good to know though.


Anyway, looking again at the code, there are only 16 instances of these two opcodes (compared to 50+ instances in the other code, most of which were for the aforementioned bit-shift / branch trick), so it may help if I just list them below:

BCC preceded by ASL THEN LDD: 1

BCS or BCC preceded by LSR: 3 (this is clearly testing current bit 0 - I may just swap that for BIT #$01 then BEQ or BNE as appropriate)

BCC preceded by EOR then BIT: 1

BCS preceded by CLC: 1 (Huh? At least I recognize what the routine it's in does, so I may just swap in the equivalent from the other code!)

BCC preceded by CMP: 4
BCS preceded by CPX: 1

BCS preceded by SBC: 1
BCC preceded by SUB: 1

BCC preceded by STD: 2

One other instance is preceded by a JSR (which itself immediately performs another JSR, so further analysis is needed)
 

Offline Kleinstein

  • Super Contributor
  • ***
  • Posts: 14199
  • Country: de
Re: Branching on the carry flag (680x MPU)
« Reply #5 on: March 30, 2023, 07:53:01 am »
The BLO and BHS op codes should only be aliases. So like an alternative name to make code possibly a little more readable. For the user is would be OK to use  BLO after a bit shift operation, if in this case it may be more confusing than helping.  It is not uncomon to find alternative names for special OP code uses, especially with processors that have target registers are parameters. E.g. a bit rotate left can be seen as adding the register to itself, a bit test is an AND or OR with itself, an XOR with itself gives a clear (with a side effect on flags).

Statement like load may not effect the carry flag and the later BCS/BCC can still have acess to the operation in the past. ASM programs sometimes do strange things and could use flag bits for temporary storage. The conditional jumps don't care on how the flag was set/cleared. There are some odd looking tricky optimizations that can be done in ASM code that makes it hard to read disassembled code.
 

Offline gslick

  • Frequent Contributor
  • **
  • Posts: 580
  • Country: us
Re: Branching on the carry flag (680x MPU)
« Reply #6 on: March 30, 2023, 09:20:32 pm »
Anyway, looking again at the code, there are only 16 instances of these two opcodes (compared to 50+ instances in the other code, most of which were for the aforementioned bit-shift / branch trick), so it may help if I just list them below:

BCC preceded by ASL THEN LDD: 1

BCS or BCC preceded by LSR: 3 (this is clearly testing current bit 0 - I may just swap that for BIT #$01 then BEQ or BNE as appropriate)

BCC preceded by EOR then BIT: 1

BCS preceded by CLC: 1 (Huh? At least I recognize what the routine it's in does, so I may just swap in the equivalent from the other code!)

As the above instances are not immediately related to subtract or compare instructions, it probably makes the most sense to consider the conditional branches to be BCC or BCS instructions.

BCC preceded by CMP: 4
BCS preceded by CPX: 1

BCS preceded by SBC: 1
BCC preceded by SUB: 1

As the above instances are immediately related to subtract or compare instructions, it probably makes the most sense to consider the conditional branches to be BHS or BLO instructions. Although if is burned into the brain that carry set means a borrow occurred after a subtract or compare, and carry clear means that a borrow did not occur, then BCC and BCS might be equally as natural. (Then it gets confusing if you switch to 6502 code where it is the opposite, where carry set means a borrow did not occur, and carry clear means a borrow did occur. The 6502 only defines BCC and BCS as the standard mnemonics, and the programmer has to remember in that world that C = /Borrow).

BCC preceded by STD: 2

STD (Store Double Accumulator) does not affect the carry flag, so you would have to look further back in the code to the most recent instruction which does affect the carry flag.
 

Offline metertech58761Topic starter

  • Regular Contributor
  • *
  • Posts: 154
  • Country: us
Re: Branching on the carry flag (680x MPU)
« Reply #7 on: March 31, 2023, 04:29:44 am »
Looking again, the STD instances were preceded by ADDD.

That last instance where there were a couple JSRs before the branch, I eventually determined there was a SUB opcode in play by the time the subroutines route back to the main flow.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf