Shop OBEX P1 Docs P2 Docs Learn Events
[resolved][puzzle] PASM beginners only — Parallax Forums

[resolved][puzzle] PASM beginners only

kuronekokuroneko Posts: 3,623
edited 2010-09-03 12:55 in Propeller 1
This code fragment was taken from the thread [post=935692]From SPIN to PASM - Code Documentation Style - Just curious[/post].
'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.
«1

Comments

  • ke4pjwke4pjw Posts: 1,173
    edited 2010-08-31 22:01
    kuroneko wrote: »
    This code fragment was taken from the thread [thread=125237]From SPIN to PASM - Code Documentation Style - Just curious[/thread].
    'if (character >= '0' && character <= '9')
    
                  cmp       character,              #$30    wc               
             if_c jmp       #fail
                  cmp       character,              #$39    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!
              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 ;)
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-31 22:07
    ke4pjw wrote: »
            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}
    

    Nice try, pass range is $30..$39, fail is everything else. In your example $30 would actually fail.
  • bill190bill190 Posts: 769
    edited 2010-08-31 22:26
    This -> if (character >= '0' && character <= '9')

    ...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).
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 01:08
    Disclaimer: Don't do this at home.

    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
    
                    fit
    
  • ColeyColey Posts: 1,112
    edited 2010-09-01 01:35
    @kuroneko

    I 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
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 01:59
    Coley wrote: »
    Totally lost me with that last one.

    How about adding some comments for PASM beginners like me

    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
    
                    fit
    
  • wjsteelewjsteele Posts: 697
    edited 2010-09-01 05:05
    Here's some simple pseudo logic I might try.

    Step #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 here
    
    

    Bill
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-09-01 05:36
    Oh, no one said anything about it being an ASCII representation of 0-9. I thought you just made a type-o. :)

    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
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 05:39
    wjsteele wrote: »
    DAT Org 0
    
    entry      SUB char, [COLOR="Red"]#[/COLOR]$30         'subtract $30 from char
               CMP char, [COLOR="Red"]#[/COLOR]$9 WC[COLOR="Red"],wz[/COLOR]    'compare it with 9... with carry (if char>9)
         IF_A  JMP [COLOR="Red"]#[/COLOR]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 here
    
    

    That's fine, I'll donate three # characters and a wz for this first working solution :) Congratulations! Now, can anyone provide a solution which doesn't destroy char?
  • wjsteelewjsteele Posts: 697
    edited 2010-09-01 07:51
    kuroneko wrote: »
    Now, can anyone provide a solution which doesn't destroy char?
    fail   ADD char, #$30  'restore original character value
    
    

    :-)

    Bill
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-09-01 08:32
    How about with one less flag..
    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 here
    

    Also 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?
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-01 09:10
    "Now, can anyone provide a solution which doesn't destroy char?"
                  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 Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-09-01 09:34
    There's a way to do it without the auxiliary constant. I've PMed the solution to Kuroneko for verification.

    -Phil
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-01 09:38
    There you go Phil... I didn't use 'char' at all or an auxiliary constant ... :lol:
    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 here
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-09-01 09:42
    LOL, Beau! :)

    How about:
            call    #is_char_a_digit
      if_nz jmp     #fail
    
    
    -Phil
  • wjsteelewjsteele Posts: 697
    edited 2010-09-01 09:51
    There you go Phil... I didn't use 'char' at all or an auxiliary constant ... :lol:

    Beau,

    Your solution looks vaguely familar! :-)

    Bill
  • ihmechihmech Posts: 179
    edited 2010-09-01 10:03
    I thought this was for beginners....aparently I'm a long way from beginner! :)
  • jazzedjazzed Posts: 11,803
    edited 2010-09-01 10:20
    Nothing says you have to jump to #fail.
  • bill190bill190 Posts: 769
    edited 2010-09-01 10:22
    ihmech wrote: »
    I thought this was for beginners....

    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...


    asciifull.gif
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 17:25
    Lots of noise while I've been away :) I received two valid solutionsA from non-beginners (non-destructive). So where are the official beginner entries (non-destructive, less than 4 instructions)? It's not rocket scienceB! Grab the propeller data sheet (6.4. Propeller Assembly Instruction Table, 2 pages) and you're ready to go.

    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.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-01 17:29
    kuroneko,

    "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!
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 17:34
    ...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 ... :)
  • jazzedjazzed Posts: 11,803
    edited 2010-09-01 18:26
    I guess this is open to non-beginner entries now.
                    cmp chr,#"0" wc,wz
        if_b        cmp chr,#"9" wc,wz
        if_a        jmp #pass
    
    fail            jmp #$
    pass            jmp #$
    
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 18:42
    @jazzed:
                    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 :)
  • jazzedjazzed Posts: 11,803
    edited 2010-09-01 19:12
    kuroneko wrote: »
    This one passes for chr > $30 ... not exactly what we're after :)
    In the example if_b really means if_ae because src and dst have unnaturally opposite roles. I could be wrong, but I think the condition is properly enclosed. :)
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 19:18
    jazzed wrote: »
    In the example if_b really means if_ae because src and dst have unnaturally opposite roles. I could be wrong, but I think the condition is properly enclosed. :)

    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.
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-09-01 19:35
    Just for the beginners who got lost. This is not truly a beginners solution, so do not get disheartened by the complex answers from very experienced people who forgot what it is like to be beginners.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-09-01 19:52
    I think this is a great puzzle for beginners, since it forces thinking outside the box. True, "outside the box" is an over-worn clich
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-01 19:57
    Cluso99 wrote: »
    This is not truly a beginners solution, ...

    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? :)
  • jazzedjazzed Posts: 11,803
    edited 2010-09-01 23:39
    kuroneko wrote: »
    Forget paired cmp's, they don't match.
    I guess you're right. How about this instead?
                    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    ret
    


    Any nop that shows up in the list below means pass.
    T0.PC 008 Ok> a 
    T0.PC 008 .      : mov     A0FC3E20     D:01F  00000039 S#020           D=01F  00000020
    T0.PC 009 .      : call    5CFC3817     D:01C  5C7C0000 S#017           D=01C  5C7C000A
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  00000020 S#030           D=01F  00000020
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  00000020 S#03A           D=01F  00000020
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3
    T0.PC 01C .      : jmp     5C7C000A   N D:000  083C01F3 S#00A           D=000  083C01F3
    T0.PC 00A .      : mov     A0FC3E2F     D:01F  00000020 S#02F           D=01F  0000002F
    T0.PC 00B .      : call    5CFC3817     D:01C  5C7C000A S#017           D=01C  5C7C000C
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  0000002F S#030           D=01F  0000002F
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  0000002F S#03A           D=01F  0000002F
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3
    T0.PC 01C .      : jmp     5C7C000C   N D:000  083C01F3 S#00C           D=000  083C01F3
    T0.PC 00C .      : mov     A0FC3E30     D:01F  0000002F S#030           D=01F  00000030
    T0.PC 00D .      : call    5CFC3817     D:01C  5C7C000C S#017           D=01C  5C7C000E
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  00000030 S#030           D=01F  00000030 Z C
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  00000030 S#03A           D=01F  00000030 C
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3 C
    T0.PC 01A nop    : nop     00000000   N D:000  083C01F3 S:000  083C01F3 D=000  083C01F3 C
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3 C
    T0.PC 01C .      : jmp     5C7C000E   N D:000  083C01F3 S#00E           D=000  083C01F3 C
    T0.PC 00E .      : mov     A0FC3E35     D:01F  00000030 S#035           D=01F  00000035 C
    T0.PC 00F .      : call    5CFC3817     D:01C  5C7C000E S#017           D=01C  5C7C0010 C
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  00000035 S#030           D=01F  00000035 C
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  00000035 S#03A           D=01F  00000035 C
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3 C
    T0.PC 01A nop    : nop     00000000   N D:000  083C01F3 S:000  083C01F3 D=000  083C01F3 C
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3 C
    T0.PC 01C .      : jmp     5C7C0010   N D:000  083C01F3 S#010           D=000  083C01F3 C
    T0.PC 010 .      : mov     A0FC3E39     D:01F  00000035 S#039           D=01F  00000039 C
    T0.PC 011 .      : call    5CFC3817     D:01C  5C7C0010 S#017           D=01C  5C7C0012 C
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  00000039 S#030           D=01F  00000039 C
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  00000039 S#03A           D=01F  00000039 C
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3 C
    T0.PC 01A nop    : nop     00000000   N D:000  083C01F3 S:000  083C01F3 D=000  083C01F3 C
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3 C
    T0.PC 01C .      : jmp     5C7C0012   N D:000  083C01F3 S#012           D=000  083C01F3 C
    T0.PC 012 .      : mov     A0FC3E3A     D:01F  00000039 S#03A           D=01F  0000003A C
    T0.PC 013 .      : call    5CFC3817     D:01C  5C7C0012 S#017           D=01C  5C7C0014 C
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  0000003A S#030           D=01F  0000003A C
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  0000003A S#03A           D=01F  0000003A Z
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3 Z
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3 Z
    T0.PC 01C .      : jmp     5C7C0014   N D:000  083C01F3 S#014           D=000  083C01F3 Z
    T0.PC 014 .      : mov     A0FC3E40     D:01F  0000003A S#040           D=01F  00000040 Z
    T0.PC 015 .      : call    5CFC3817     D:01C  5C7C0014 S#017           D=01C  5C7C0016 Z
    T0.PC 017 .      : cmpsub  E37C3E30 ZCN D:01F  00000040 S#030           D=01F  00000040 C
    T0.PC 018 C      : cmp     87703E3A ZCN D:01F  00000040 S#03A           D=01F  00000040
    T0.PC 019 NC     : jmp     5C4C001B   N D:000  083C01F3 S#01B           D=000  083C01F3
    T0.PC 01B .      : jmp     5C7C001C   N D:000  083C01F3 S#01C           D=000  083C01F3
    T0.PC 01C .      : jmp     5C7C0016   N D:000  083C01F3 S#016           D=000  083C01F3
    T0.PC 016 .      : jmp     5C7C0016   N D:000  083C01F3 S#016           D=000  083C01F3
    T0.PC 016 .      : jmp     5C7C0016   N D:000  083C01F3 S#016           D=000  083C01F3
    
Sign In or Register to comment.