Check specific bit of a byte
Hi,
for my morse keyer, I have to get the sequence for every letter. It is either "dit" or "dah" some times, e.g. the letter A is "dit dah", the letter B is "dah dit dit dit", and so on. A PIC programmer told me how he stored the "codes": one byte per character, consisting of zeroes, the startbit and a 0 for "dit" and a 1 for "dah". So a A would be stored as %0000_0101, a B would be %0001_1000, etc. The program shall read from Bit #7 to #1, if it's 0, continue reading, it it's 1, go ahead and issue dit or da for 0 or 1. My implementation looks like that:
But this code doesn't work, I don't hear any output. The methods dit and dah are definitely working, I tested them.
What am I doing wrong?
for my morse keyer, I have to get the sequence for every letter. It is either "dit" or "dah" some times, e.g. the letter A is "dit dah", the letter B is "dah dit dit dit", and so on. A PIC programmer told me how he stored the "codes": one byte per character, consisting of zeroes, the startbit and a 0 for "dit" and a 1 for "dah". So a A would be stored as %0000_0101, a B would be %0001_1000, etc. The program shall read from Bit #7 to #1, if it's 0, continue reading, it it's 1, go ahead and issue dit or da for 0 or 1. My implementation looks like that:
sign := byte[@A]
repeat i from 7 to 0
if sign[i] == 1
repeat j from i-1 to 0
case sign[j]
0 : dit
1 : dah
waitdit
quit
DAT
A byte %0000_0101
dit and dah are methods, sign, i and j are declared as byte.But this code doesn't work, I don't hear any output. The methods dit and dah are definitely working, I tested them.
What am I doing wrong?

Comments
1) Use bitmasks (|<) and the bit logical operations (& | ^ !)
2) Move your value to one of the unused special function registers (OUTB or DIRB) and use the bit access syntax there
To check for bit x, do: "IF sign & |< x" or "IFNOT sign & |< x" (note: IFNOT is one word).
con { ----------------- } { B I T W O R K } { ----------------- } pub rd_bit(value, pos) '' Returns value.pos (0 or 1) return (value >> pos) & 1 pub wr_bit(value, pos, bit) '' Returns modifed value with value.pos set to bit if (bit & 1) ' use lsb return set_bit(value, pos) else return clear_bit(value, pos) pub set_bit(value, pos) '' Returns value with bit at pos set (1) return value | (1 << pos) pub clear_bit(value, pos) '' Returns value with bit at pos clear (0) return value & !(1 << pos)A couple years ago I did lighting control for this display, which included Morse Code output of the character names (Mourningstar and Typhon) from the back of their costumes:
At that particular convention, G4 TV did an interview with Steve Wang (his shop built the display) and the Morse Code IFF output from the characters was a big topic of discussion. I chucked it in for fun as I had an extra cog!
Here's the code I converted from a Scott Edwards program for the BASIC Stamp 1 (grandfather of the Propeller); you'll need to define timing constants.
pub morse(char, pin) | key, idx, len '' Output char as Morse Code on pin '' -- makes pin an output outa[pin] := 0 dira[pin] := 1 key := ucase(char) ' convert to upper case idx := lookdown(key : "A".."Z", "0".."9") ' if alpha-numeric if (idx > 0) key := byte[@Alphas][idx-1] ' convert to Morse len := (key & %111) ' extract length if (len == 7) ' adjust if required len := 6 elseif (len == 6) key &= %11111011 repeat len ' output char outa[pin] := 1 ' led on if ((key & %1000_0000) == 0) ' if 0 pause(DIT_TIME) ' dit else ' if 1 pause(DAH_TIME) ' dah outa[pin] := 0 ' led off key <<= 1 ' prep for next bit pause(DIT_TIME) ' inter-flash delay elseif (key == " ") ' if space pause(WRD_TIME) ' pad with word delay pub ucase(ch) '' Converts lowercase ch to uppercase if ((ch => "a") and (ch =< "z")) ch -= 32 return ch pub pause(ms) | tix, t tix := clkfreq / 1_000 t := cnt repeat ms waitcnt(t += tix) dat Alphas byte %01000_010 ' A byte %10000_100 ' B byte %10100_100 ' C byte %10000_011 ' D byte %00000_001 ' E byte %00100_100 ' F byte %11000_011 ' G byte %00000_100 ' H byte %00000_010 ' I byte %01110_100 ' J byte %10100_011 ' K byte %01000_100 ' L byte %11000_010 ' M byte %10000_010 ' N byte %11100_011 ' O byte %01100_100 ' P byte %11010_100 ' Q byte %01000_011 ' R byte %00000_011 ' S byte %10000_001 ' T byte %00100_011 ' U byte %00010_100 ' V byte %01100_011 ' W byte %10010_100 ' X byte %10110_100 ' Y byte %11000_100 ' Z Numbers byte %11111_101 ' 0 byte %01111_101 ' 1 byte %00111_101 ' 2 byte %00011_101 ' 3 byte %00001_101 ' 4 byte %00000_101 ' 5 byte %10000_101 ' 6 byte %11000_101 ' 7 byte %11100_101 ' 8 byte %11110_101 ' 9Scott uses a clever scheme of encoding the length (number of dits and dahs) in the lower three bits of the character code. See page 39 of this document for Scott's original BS1 project:
-- http://www.parallax.com/Portals/0/Downloads/appnt/stamps/bs1Appnotes.pdf
Code is at GitHub: https://github.com/qsuscs/PropCW