Author Topic: STM8 assembly - some kind of arithmetic op to set carry if two values equal?  (Read 509 times)

0 Members and 1 Guest are viewing this topic.

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 857
  • Country: gb
In STM8 assembly language, is there some kind of arithmetic operation I can do that will have the effect of setting the carry flag if two values are equal, and clear the carry if they are not?

I know there is the CP dst, src instruction, but that only sets carry if src is larger than dst. I'm wondering if there is some kind of arithmetic trickery that can be done with possibly other instructions that modify carry, such as ADD, SUB, DIV, etc.

What I'm trying to do is generate a sequence of instructions, without branching, to set/clear several I/O port pins, but the state each is set to depends on whether an argument passed into the function matches its position. I thought the BCCM instruction might be useful here, if I can only get the carry set appropriately...

Code: [Select]
LD A, (3, sp) ; load func arg to A reg
; here, set carry = (A == 0)
BCCM 0x5000, #3
; here, set carry = (A == 1)
BCCM 0x5005, #0
; here, set carry = (A == 2)
BCCM 0x5000, #6
; here, set carry = (A == 3)
BCCM 0x500F, #2
; etc...
 

Offline rhodges

  • Regular Contributor
  • *
  • Posts: 244
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
Something like this?
Code: [Select]
LD A, (3, sp) ; load func arg to A reg
sub a, #1 ; here, set carry = (A == 0)
BCCM 0x5000, #3
sub a, #1 ; here, set carry = (A == 1)
BCCM 0x5005, #0
sub a, #1 ; here, set carry = (A == 2)
BCCM 0x5000, #6
Currently developing STM8 and STM32. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 
The following users thanked this post: I wanted a rude username

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 857
  • Country: gb
Yes! That does the trick. :D

If I'm understanding correctly, by decrementing the position argument itself at each step, the subtraction will have a negative result (i.e. underflow) and the carry bit set when needed. At the subsequent step, it will go back to no carry, as it's just decrementing from 255. I suppose this means I can't have more than 255 steps - as it would underflow twice -  but I don't need to.

I must be having a bit of brain drain today to not be able to think it would be that simple.

Thanks very much. :-+
 

Offline ucanel

  • Regular Contributor
  • *
  • Posts: 133
  • Country: tr
Sorry for the interruption but after i saw this topic i think it would be efficent to do it with jump  table and i do not know stm8 assembly so i searched for it for more than a hour but could not got it. So i wonder it now :)

My question how is Program Counter manipulation done in Stm8 assembly?
I was doing it for PIC mcus like this:
Code: [Select]
MOV      0x04,W  ; load xxx to accumulator (W)
ADDWF PCL,F  ; PC = PC + Accumulator [add accumulator (W) to the Program counter and store it to the File ( Program Counter) ]
 

Offline chickenHeadKnob

  • Frequent Contributor
  • **
  • Posts: 932
  • Country: ca
  • doofus programus semi-retiredae
In general when I want to do some Boolean operation on an 8 bit micro and it is not directly supported in the instruction set and I want to avoid branching, I resort to 256 byte lookup tables. Input conditions form the index into the table. Might need 2 tables if'n  you need to do something more complicated than set/clear.
 

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 857
  • Country: gb
My question how is Program Counter manipulation done in Stm8 assembly?

I don't believe you can manipulate the program counter directly on STM8. You can only do so with jump, call, return, etc. instructions (e.g. JRA 0x20 - adds 0x20 to PC).
 

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 857
  • Country: gb
In general when I want to do some Boolean operation on an 8 bit micro and it is not directly supported in the instruction set and I want to avoid branching, I resort to 256 byte lookup tables. Input conditions form the index into the table. Might need 2 tables if'n  you need to do something more complicated than set/clear.

I can't afford the memory for a lookup table.

What I'm actually doing is writing some STM8 C code that will, at run-time, generate some functions in raw assembly and shove them in RAM, then they can be called when necessary. It's because I want to have code that uses atomic BSET/BRES (and BCCM now I have a solution for that) instructions to manipulate port I/O, but the trouble with those is that they only accept hard-coded register addresses (i.e. set at compile-time) and not, for example, indirect pointers in X/Y registers. That would normally preclude me from having code where I/O registers are configured dynamically, but this way gets around that. :)
 

Offline ucanel

  • Regular Contributor
  • *
  • Posts: 133
  • Country: tr
...
Quote

I don't believe you can manipulate the program counter directly on STM8. You can only do so with jump, call, return, etc. instructions (e.g. JRA 0x20 - adds 0x20 to PC).

I thought a way but that is not good there must be an elegant way.
We have our function named PCMANIPULATOR
Get it's address,
add whatever offset value desired,
push this PCMANIPULATOR address + offset to the stack
issue a RETURN instruction.

 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 539
  • Country: ru
I can't afford the memory for a lookup table.

What I'm actually doing is writing some STM8 C code that will, at run-time, generate some functions in raw assembly and shove them in RAM
But your generator code consumes flash anyway. You can just generate a single BSET 0, #0 ; RET in RAM at startup and have a function (in flash) with a switch or LUT that will set correct addr, bit and SET/RES op on the fly and call the RAM snippet each time you were going to call your original RAM code. This way you’ll save even more RAM for no additional cost (the flash code size should be comparable to your generator’s).
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3457
  • Country: us
Quote
is there some kind of arithmetic operation I can do that will have the effect of setting the carry flag if two values are equal, and clear the carry if they are not?
"Compare" is almost always implemented as a "subtract, but don't save the result", which will usually not affect a carry flag in the way that you want.  Rhodge's solution or similar will work for the specific case you're looking at...
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf