Searching \ for 'PIC 16Cxx programming challenge' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/devprogs.htm?key=programming
Search entire site for: 'PIC 16Cxx programming challenge'.

Truncated match.
PICList Thread
'PIC 16Cxx programming challenge'
1997\06\06@050729 by Eric Smith

flavicon
face
I've finally gotten back to PIC programming, after a series of projects using
MIPS 4300i and 4600 RISC chips, and H8/300L microcontrollers.  The PIC is
more fun, IMHO.  I was just writing up some 16Cxx routines I find handy, in
preparation for adding them to my web page, when it occurred to me that they
might make a nice programming challenge.  I'll describe them here, and I'll
put the code on my web page in about a week.

All three routines use only the W and status registers, don't modify any
RAM, and don't use subroutines.


toupper - equivalent to the toupper() library function in C.
   Entry:  character in W
   Exit:   if the character was in the range 'a'..'z'
               return the corresponding upper case character 'A'..'Z'
           else
               return with W *unchanged*

   6 instruction words, 7 instruction cycles (including return)


toascii - convert the low four bits of W into the ASCII representation of
         a hexadecimal digit
   Entry:  W contains a value in the range 00h..0fh
   Exit:   W contains a the character, '0'..'9', 'A'..'F'
           if the input was out of range, the output is unspecified

   6 instruction words, 7 instruction cycles (including return)


ishex - convert the ASCII representation of a hex digit to a binary value
   Entry:  W contains a character
   Exit:   if the character was a valid hex digit ('0'..'9','A'..'F','a'..'f')
               return the corresponding value 00h..0fh, with STATUS.Z set
           else
               return with W *unchanged* and STATUS.Z clear

   18 instruction words, 8 to 17 cycles (including return)

   note - could be made shorter and faster if it didn't accept both cases
          could be made shorter and slower if it called toupper


Hint - all three routines use the same "trick".  Those of you familiar with
the technique may wish to refrain from posting the solutions immediately
to give others a chance to work it out.

Cheers,
Eric

http://www.brouhaha.com/~eric/pic/

1997\06\06@141453 by sdattalo

face
flavicon
face
Eric Smith wrote:
>
> I've finally gotten back to PIC programming,

Welcome back!

Rather than spoiling the fun for everyone, I shaved one cycle
off of the 'toascii' routine. There are no comments, so the 'hint'
is only partially revealed.

> toascii - convert the low four bits of W into the ASCII representation of
>           a hexadecimal digit
>     Entry:  W contains a value in the range 00h..0fh
>     Exit:   W contains a the character, '0'..'9', 'A'..'F'
>             if the input was out of range, the output is unspecified
>
>     6 instruction words, 7 instruction cycles (including return)

; 5 instructions words, 6 cycles:
toascii
       ADDLW   -0x0a
       SKPNC
        ADDLW  'A'-'9' - 1
       ADDLW   '0' + 0x0a
       RETURN


Scott
--
"The problem with television is not the resolution."
                                Hugh. F. Frohbach

1997\06\09@194607 by Dwayne Reid

flavicon
face
{Quote hidden}

Hiya Eric, Scott

I posted a set of routines to the list back in March: HEXASCII (hex to
Ascii), ASCIIHEX (ascii to hex) and UPCASE.  I dug them out when I read
Eric's challange and like Scott, I'll repost my version of toascii without
comments.

HEXASCII        ;Convert hex nybble to ascii character
;***********    ;written by Dwayne Reid
;* enters with:         hex nybble (0-F) in w
;* uses subroutines:    none
;*      registers:      w
;*      bits/flags:     none
;* returns:             ascii character in w
;*
   andlw       b'00001111'
   addlw       6
   skpndc
     addlw     7
   addlw       (0x30-6)
   return

This version is 6 instructions long, but the 1st instruction can be removed
(I included it because I often pack 2 digits into a single byte).  That puts
it on par with Scott's routine.

I'm looking forward to seeing Eric's UPCASE routine: mine is 10 instructions
and 11 cycles including the return.

UPCASE          ;Convert lower case ascii character to upper case
;***********    ;Written by Dwayne Reid
;* enters with:         any character from 00 - FF in w
;* uses subroutines:    none
;*      registers:      w
;*      bits/flags:     none
;* returns:             original value in w EXCEPT ascii a-z converted to A-Z
;*
   addlw       -(0x7B)
   skpnc
     goto      UCaseX1
   addlw       0x1A
   skpc                        ;
     goto      UCaseX2
   addlw       0x41
   return

UCaseX2
   addlw       -(0x1A)
UCaseX1
   addlw       0x7B
   return
Dwayne Reid   <spam_OUTdwaynerTakeThisOuTspamplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax

1997\06\10@105506 by sdattalo

face
flavicon
face
Dwayne Reid wrote:
> I posted a set of routines to the list back in March: HEXASCII (hex to
> Ascii), ASCIIHEX (ascii to hex) and UPCASE.  I dug them out when I read
> Eric's challange and like Scott, I'll repost my version of toascii without
> comments.

<snip>
>     skpndc

 Oh yeah! The 'used-once-in-a-blue-moon-digit-carry'.

> I'm looking forward to seeing Eric's UPCASE routine: mine is 10 instructions
> and 11 cycles including the return.

Here's the 6 instruction/7 cycle 'toupper'

toupper
       ADDLW   -('z'+1)
       ADDLW   'z'-'a'+1
       SKPNC
        ADDLW  'A'-'a'
       ADDLW   'a'
       RETURN

It's probably clearer now. The hint has been all but exposed. Roll-over
arithmetic is the key.

BTW. Does anyone have a good explanation why
       ADDLW   -('z'+1)     ==> -('z'+1) evaluates correctly to 0x85
assembles differently than
       ADDLW   -'z'-1       ==> -'z'-1 evaluates incorrectly to 0x87

(I'm using the pre-historic version 3.12.00 of MPLAB)

Scott

--
"The problem with television is not the resolution."
                                Hugh. F. Frohbach

1997\06\10@204240 by Mike Keitz

picon face
On Tue, 10 Jun 1997 07:52:35 -0700 Scott Dattalo <.....sdattaloKILLspamspam@spam@unix.SRI.COM>
writes:
>Dwayne Reid wrote:
>> I posted a set of routines to the list back in March: HEXASCII (hex
>to
>> Ascii), ASCIIHEX (ascii to hex) and UPCASE.  I dug them out when I
>read
>> Eric's challange and like Scott, I'll repost my version of toascii
>without
>> comments.
>
><snip>
>>     skpndc
>
>  Oh yeah! The 'used-once-in-a-blue-moon-digit-carry'.

If the ASCII code for 'A' were 0x40 rather than 0x41, then the DC could
be used to write a 3 instruction (plus return) toascii.  But it isn't,
and using DC has no advantage over the 8th-bit Carry.


>BTW. Does anyone have a good explanation why
>        ADDLW   -('z'+1)     ==> -('z'+1) evaluates correctly to 0x85
>assembles differently than
>        ADDLW   -'z'-1       ==> -'z'-1 evaluates incorrectly to 0x87
>
>(I'm using the pre-historic version 3.12.00 of MPLAB)

A couple of clues: Ver. 3.22.00 does the same thing, but
       ADDLW   0-'z'-1
will evaluate to 0x85.  My "good explanation" is that the - sign with
nothing on the left is negation, and it (at least unconventionally, if
not mistakenly) has lower priority than subtraction.  Writing the
negation as a subtraction from zero increases the priority so the
expression evaluates from left to right as expected.

-'z'-1 -->  -('z'-1), not -('z') + -(1)
0-'z'-1 --> (0-'z')-1

Some of the early MPALCs did really strange things with compile-time
expressions.  They are getting better...

1997\06\12@101248 by Dwayne Reid

flavicon
face
>On Tue, 10 Jun 1997 07:52:35 -0700 Scott Dattalo <sdattalospamKILLspamunix.SRI.COM>
>writes:
>>Dwayne Reid wrote:
>><snip>
>>>     skpndc
>>
>>  Oh yeah! The 'used-once-in-a-blue-moon-digit-carry'.
>
>If the ASCII code for 'A' were 0x40 rather than 0x41, then the DC could
>be used to write a 3 instruction (plus return) toascii.  But it isn't,
>and using DC has no advantage over the 8th-bit Carry.

Hiya Mike, Scott.

Mike - I don't disagree with you.  I used DC because I wrote HEXASCII
shortly after I had written my 2-digit-BCD-counter-in-1-byte routines, and
had used DC to determine if the least significant nybble had wrapped from 9
to 0.  It seemed like the logical choice for HEXASCII routine, and works
just fine.  It has the disadvantage that it is PIC specific whereas Scott's
version will probably work with any micro.

Just for the heck of it, here are my 2 digit BCD counter routines.  Any
optimisation hints or critism gratefully accepted.


;2 digit BCD UP counters: units in lower nibble, tens in upper
;can increment by 1...9 without error, intermediate results kept in w
CNT1UP
   incf        CNTR1,W         ;inc counter --> w
   addlw       6               ;now 10?  if so, wrap to 0, inc nxt digit
   skpdc                       ;did wrap occur?
     addlw     -6              ;no, restore
   addlw       60              ;did upper digit wrap?
   skpc
     addlw     -60             ;no, restore
   movwf       CNTR1           ;new count  NOTE: z=1 if wrapped to 00
   return

;2 digit DOWN counter: units in lower nibble, tens in upper
;can decrement by 1...9 without error, intermediate results kept in w
CNT1DN
   movfw       CNTR2
   addlw       -1              ;dec counter --> w, update flags
   skpc                        ;tens underflow?
     addlw     -60             ;adjust
   skpdc                       ;units undeflow?
     addlw     -6              ;adjust
   movwf       CNTR2           ;new count: z=1 if decremented to 00
   addlw       1               ;allow cascading: z=1 if underflowed to 99
   return


;typical usage for counter
;get each digit for display
   movfw       CNTR1           ;byte 3: display 1 units
   btfsc       DSCNT,4
     swapf     CNTR1,W         ;byte 4: display 1 tens
   call        SevenSeg        ;translate both bytes
   goto        DISNEW

Dwayne Reid   <.....dwaynerKILLspamspam.....planet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax

1997\06\12@151740 by Bob Fehrenbach

picon face
Dwayne Reid <EraseMEdwaynerspam_OUTspamTakeThisOuTPLANET.EON.NET> wrote:
>;2 digit DOWN counter: units in lower nibble, tens in upper
>;can decrement by 1...9 without error, intermediate results kept in w
>CNT1DN
>    movfw       CNTR2
>    addlw       -1              ;dec counter --> w, update flags
>    skpc                        ;tens underflow?
>      addlw     -60             ;adjust
>    skpdc                       ;units undeflow?
>      addlw     -6              ;adjust
>    movwf       CNTR2           ;new count: z=1 if decremented to 00
>    addlw       1               ;allow cascading: z=1 if underflowed to 99
>    return

It seems to me that the addlw 1 just before the return should be
  addlw h'99' .


--
Bob Fehrenbach    Wauwatosa, WI     bfehrenbspamspam_OUTexecpc.com

1997\06\12@153448 by Bob Fehrenbach

picon face
Make that addlw -h'99'
               ^ left this out in previous post.

--
Bob Fehrenbach    Wauwatosa, WI     @spam@bfehrenbKILLspamspamexecpc.com

More... (looser matching)
- Last day of these posts
- In 1997 , 1998 only
- Today
- New search...