[resolved][puzzle] PASM beginners only
kuroneko
Posts: 3,623
This code fragment was taken from the thread [post=935692]From SPIN to PASM - Code Documentation Style - Just curious[/post].
Make it smaller! Bonus points for keeping character alive.
'if (character >= '0' && character <= '9')
cmp character, #[COLOR="Red"]$30[/COLOR] wc
if_c jmp #fail
cmp character, #[COLOR="Red"]$39[/COLOR] wc,wz
if_nc_and_nz jmp #fail
pass {do stuff here if condition is true}
fail {continue here if the condition is true or false}
Make it smaller! Bonus points for keeping character alive.

Comments
cmp character,#10 wc if_nc jmp #fail pass {do stuff here if condition is true} fail {continue here if the condition is true or false}At least that is all my sleepy head can come up with
Nice try, pass range is $30..$39, fail is everything else. In your example $30 would actually fail.
...is if you press one of the keys...
0, 1, 2, 3, 4, 5, 6, 7, 8, or 9
on the keyboard (ASCII $30 to $39)...
Then (do something) - [Pass]
Otherwise (do something else) - [Fail]
Edit: That is hexadecimal (hex 30 to hex 39).
A version just using jump instructions:
DAT org 0 entry [COLOR="Red"]jmpret char, #$30 wc,nr[/COLOR] long 0[$30 - $] [COLOR="Red"]if_nc jmpret char, #$3A wc,nr[/COLOR] fail waitpeq $, #0 long 0[$3A - $] [COLOR="Red"]if_nc jmp #fail[/COLOR] pass waitpeq $, #0 char long $34 fitI thought this was for PASM beginners....... :smilewinkgrin:
Totally lost me with that last one.
How about adding some comments for PASM beginners like me
Regards,
Coley
Apologies, I just thought I point out what's possible to get the thinking-outside-the-box going. Comments coming up:
DAT org 0 ' [COLOR="Blue"]jmpret safe, target nr[/COLOR] is effectively [COLOR="Blue"]jmp target[/COLOR], advantage of using ' it like this is that you can define the destination slot yourself ' (which is normally set to 0 for a jmp). ' ' AFAIK the effect of [COLOR="Blue"]wz[/COLOR] is that Z is always cleared. [COLOR="Blue"]wc[/COLOR] OTOH updates ' the C flag for an unsigned compare between destination and source. ' So don't believe everything the manual tries to tell you (but it's ' good for a laugh). ' first instruction (actions taken) ' - cmp char, #$30 wc ' - jmp #$30 entry [COLOR="Red"]jmpret char, #$30 wc,nr[/COLOR] long 0[[COLOR="Red"]$30[/COLOR] - $] ' padding ' second instruction (conditional, if char => $30) ' - cmp char, #$3A wc ' - jmp #$3A [COLOR="Red"]if_nc jmpret char, #$3A wc,nr[/COLOR] ' cog register $30 fail waitpeq $, #0 ' done long 0[[COLOR="Red"]$3A[/COLOR] - $] ' padding ' third instruction (conditional, if char => $3A) ' - jmp #fail [COLOR="Red"]if_nc jmp #fail[/COLOR] ' cog register $3A pass waitpeq $, #0 ' done char long $34 fitStep #1: Take the value and subtract $30 from it. That'll give you a value from $0 to $9 if it is within range. If it is less than 30, just ignore it, it'll roll over to a higher value, which is ok. If it is higher, still ok.
Step #2: Compare that value to see if it is greater than 9. (CMP char,$9 WC)
Step #3: If it is conditional jump to "fail" based on the C flag (IF_A)
Otherwise it will simply fall through to "pass".
Off the top of my head, the code would look something like this:
DAT Org 0 entry SUB char, $30 'subtract $30 from char CMP char, $9 WC 'compare it with 9... with carry (if char>9) IF_A JMP fail 'if carry flag is set, it's greater than 9, so jump to fail pass {do stuff here if condition is true} 'otherwise, just falls through here if it is withing range fail {continue here if the condition is true or false} 'always executes this part hereBill
In your original code, the entry point was not made clear. If the Z flag was set, using IF_A would not work in your code below.
Thanks for the exercise! I was not aware of the IF_A. (IF_NC_AND_NZ)
Regards,
Terry
That's fine, I'll donate three # characters and a wz for this first working solution
:-)
Bill
DAT Org 0 entry SUB char, #$30 'subtract $30 from char CMP char, #$0A WC 'compare it with 10... with carry (if char>9) ADD char,#$30 'restore char IF_C JMP #fail 'if carry flag is set, it's greater than 9, so jump to fail pass {do stuff here if condition is true} 'otherwise, just falls through here if it is withing range fail {continue here if the condition is true or false} 'always executes this part hereAlso what would happen if a Carriage Return ($0D) were assigned to char. I know you would get an underflow, because we are dealing with unsigned values. There would be no easy way to restore the original value of char, would there?
cmp character, #$30 wc if_nc cmp thirtynine, character wc if_c jmp #fail pass {do stuff here if condition is true} fail {continue here if the condition is true or false} 'Note: predefine thirtynine thirtynine long $39-Phil
DAT Org 0 entry SUB chr, #$30 'subtract $30 from chr CMP chr, #$9 WC,wz 'compare it with 9... with carry (if chr>9) IF_A JMP #fail 'if carry flag is set, it's greater than 9, so jump to fail pass {do stuff here if condition is true} 'otherwise, just falls through here if it is withing range fail {continue here if the condition is true or false} 'always executes this part hereHow about: -Phil
Beau,
Your solution looks vaguely familar! :-)
Bill
It is! If anyone has any questions about the above, this is the time to ask.
Hint: *Any* key on the keyboard can be pressed and the hex "ASCII" value for that would be "character". So character could be...
A
a
(
7
W
0
etc.
Only if it is: 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9 would it pass.
The hex ASCII numbers for these would be...
$30, $31, $32, $33, $34, $35, $36, $37, $38, or $39
ASCII tables many times show numbers for decimal, hex, and octal. Hex is typically used in my experience. Here is an ASCII table...
BTW, Beau, re-using Bill's entry wasn't very nice
A Both different and not the same as the one I came up with (we all used the same basic idea though).
B ... and doesn't involve undocumented features.
"BTW, Beau, re-using Bill's entry wasn't very nice"
...Touche, but I could say the same thing about you borrowing my original code ... I won't hold a grudge if you don't ... all fun anyway, lets exercise the mind!
Ah, you got me there, at least I was considering asking for permission ...
cmp chr,#"0" wc,wz if_b cmp chr,#"9" wc,wz if_a jmp #pass fail jmp #$ pass jmp #$cmp chr,#"0" wc,wz if_b cmp chr,#"9" wc,wz if_a jmp #pass fail jmp #$ pass jmp #$This one passes for chr > $30 ... not exactly what we're after
I actually ran this code on the demoboard and that's what I got. If I change if_b to its opposite if_ae the test passes for chr > $39. Third time lucky?
Forget paired cmp's, they don't match.
If you refer to [post=935826]posting 5[/post], well, I thought it was obvious that this isn't a beginners solution. Do I have to spell out everything?
mov t0,#$20 ' test for less than $30 call #checknum mov t0,#$2f ' test for less than $30 call #checknum mov t0,#$30 ' test for equal $30 call #checknum mov t0,#$35 ' test for middle call #checknum mov t0,#$39 ' test for equal $39 call #checknum mov t0,#$3a ' test for greater than $39 call #checknum mov t0,#$40 ' test for greater than $39 call #checknum jmp #$ checknum cmpsub t0, #$30 wc,wz,nr if_c cmp t0,#"9"+1 wc,wz if_nc jmp #fail pass nop fail jmp #checknum_ret checknum_ret retAny nop that shows up in the list below means pass.