Made my First Assembly code - ASCII Case Swapping
speewave
Posts: 11
So it's been a while since i've tried to do any Coding on my Prop, and for whatever reason i felt like i wanted to just skip ahead of Spin and do some Assembly Coding *Something about it just fascinates me i guess*
What i did was made a Case Swapping thing - so "A" -> "a" and vice versa - Seems to work quite well! Done with the Quickstart board so pins are aligned for LEDS on 16-23 (but can be easily moved)
Anyway a lot of it was a bit of quick work and a bit of CTRL+F on the Prop Manual, but it was a challenge to see if i can do something in assembly on the prop, So from here i was just kinda looking for some comments, and i'm posting my code in case anyone ever needs something like this
So heres the Code : https://gist.github.com/sgulgas/ff905f98d99a93b3763c
A few questions i had:
What i did was made a Case Swapping thing - so "A" -> "a" and vice versa - Seems to work quite well! Done with the Quickstart board so pins are aligned for LEDS on 16-23 (but can be easily moved)
Anyway a lot of it was a bit of quick work and a bit of CTRL+F on the Prop Manual, but it was a challenge to see if i can do something in assembly on the prop, So from here i was just kinda looking for some comments, and i'm posting my code in case anyone ever needs something like this
So heres the Code : https://gist.github.com/sgulgas/ff905f98d99a93b3763c
A few questions i had:
- How could i incorperate this to a program - or Make it so i can pass a word or whatever and have it shift the case inside another program *Either in Spin or PASM*
- Is there a better way to toggle the Lowercase Flag than Subbing and Adding 32?
- Was this the right way to do the comparison (AND x,y nr,wz)?
- I could've easily subtracted against the variable for lower case, instead went with #32
- For whatever reason i Or'ed the Pins to OUTA instead of MOVing them - It worked well enough for this case, helped
Comments
A simpler methode than ADD/SUB and AND-Test is to use XOR 32 this will flip the bit that indicates lower / upper case.
You also can read the characters from Hub and modify all the following characters in a loop until a zero is reached, so it will be usable for Spin strings. For that you can pass the start address of the string in the PAR register with the second parameter at cognew.
I think this will be a good exercise to learn the interaction between Spin and PASM.
Andy
I think (and hope) using or is the more common way of setting pin states on in PASM.
IMO, using or is "cleaner" (I supose that's subjective). With mov you have to make sure all the I/O pins used by the cog are set at once. If you're using other I/O pins (say debug LEDs) then these other I/O pins need to be included in the mov mask or they will be set low.
In order for code running in another cog to make use of the case swapper, there needs to be a way for them to communicate. This is most commonly done by passing an address through par, and instead of mov swapbyte, a, you’d use rdbyte swapbyte,par to read from a single address. The next step is reading from multiple addresses, which involves first copying par to another register mov temp,par, and reading from that with offsets as needed to address other bytes.
Andy has already hit upon the idea of xor’ing to swap case, so I’ll just mention here that when I’m performing operations on bits, I like to write my operands in binary as a way to keep things straight in my mind. You check swapbyte against caps, which is set to %00100000, but to toggle you add or subtract decimal 32, which requires some extra thought to make sense of. Also, you only really need to declare constants in registers if they exceed nine bits (#511), as in mov temp, #%1_1111_1111.
Using an and instruction with nr turns it into a test instruction. So test swapbyte,#%0010_0000 wz does the same thing. You can also use the cmp instruction to compare if swapbyte is greater, equal, or less than another value.
I agree with Duane, that or’ing outputs is cleaner as it only affects the specified bits, though there are times when mov is useful if you want to set some bits and clear others in a single operation, as you do want to do in this case. I think it's also cleaner to shift first, and then or with the output, as in shl swapbyte,#16, or outa,swapbyte, but again in this case that'd cause the current and previously lit LEDs to light, whereas mov outa,swapbyte turns off the unused LEDs. You can use andn outa, pins to first blank all of the LEDs, then or the new pattern in, or simply use mov.
Finally, a simple tip for the donothing loop; $ is interpreted as meaning this address. Therefore, jmp #$ loops in place forever. I often use it in djnz counter,#$ which loops in place until counter equals zero. It saves me from cluuttering up my code with a bunch of extra labels that are only used for short loops.
Congrats on an ambitious first assembly program; I always start out with blinking LEDs. And speaking of which, I’ve posted many of my early routines here, cleaned up and commented. Your code swapper is very similar to something I wrote to understand how multiple cogs can interact. One cog receives a byte from the serial terminal, a second swaps the case, and a third transmits it back, all in assembly.
Also check out some of the links in Duane’s sig. I found deSilva's tutorial particularly helpful. I don't see it in the list, but Phil Pilgrim's Tricks & Traps also has lots of useful information.
Good catch, this was something i hadn't thought of, as this was a quick challenge more than anything application ready, but it's something i'll try to work on! Thanks
For whatever reason, XOR wasn't working right one of the times i tried it (In my crazed amount of iterations, i probably just messed it up and went with Add\Sub\Test instead) now that you mentioned it, i tried it and it worked well, so thanks!
Thanks for this info - the info on TEST in the Prop Manual didn't seem as clear to me as AND with NR,WZ so i went with that... Now i know, so thank you!
Thanks! For whatever reason i went with something that wouldn't rely on the clock as i wasn't getting it to work right the one time for whatever reason and wasn't clear to me (just need to spend more time on it i guess) i went with something that didn't need me to setup the clock instead and i figured ASCII stuff would be something interesting to work with!
Seems Interesting i'll have to check them out! As far as the tutorials you mentioned, i'll have to take a look at Phil's Tricks and Traps when i get home Seems incredibly helpful!, So far i've only used deSilva's thing and the Prop Manual to get this far. so anything helps... I want to try to do some cool stuff with the prop and the Assembly language