Truncated match.
PICList
Thread
'Switch statements (was: Odd PCL behaviour on 16C84'
1998\10\13@105911
by
Dave Johnson
|
>I use the modification of PCL extensively to implement switch statements.
Is this a "standard" way to do switch statements, by messing with the
PCL? I've been wondering about this. If the set of things you're
switching on is consecutive, it seems a jump table arrangement would be
good, but what if they're not? In my case, I need to switch on various
non-consecutive ASCII characters. Currently I'm doing something like this:
-----
dispatch
; compare w with each known command in turn
movf savechar, w ; check for ques
tion mark
sublw '?'
btfsc status, z
goto dosomething
movf savechar, w ; check for excl
amation point
sublw '!'
btfsc status, z
goto dosomethingelse
...etc...
; default: if we get here, we didn't recognize any command
default
call defaultaction
return
-----
I use gotos to call the individual routines, with return statements at
the ends of those routines, so that once they're done they return to
wherever dispatch was called from. This lets me skip all the other tests
once I've found a valid case.
Is this reasonable? Brain dead? Suggestions/comments are welcome.
Dave Johnson
1998\10\13@170654
by
Clyde Smith-Stubbs
|
On Tue, Oct 13, 1998 at 07:57:31AM -0700, Dave Johnson wrote:
> good, but what if they're not? In my case, I need to switch on various
> non-consecutive ASCII characters. Currently I'm doing something like this:
> movf savechar, w ; check for qu
estion mark
> sublw '?'
> btfsc status, z
> goto dosomething
> movf savechar, w ; check for ex
clamation point
> sublw '!'
> ...etc...
>
> Is this reasonable? Brain dead? Suggestions/comments are welcome.
It's not unreasonable, but it can be improved, like so:
movf savechar,w
xorlw '?'
btfsc status,z
goto dosomething
xorlw '!'^'?'
btfsc status,z
goto dosomethingelse
xorlw 'A'^'!'
btfsc status,z
goto dosomeotherthing
...etc...
This avoids having to reload the switched value each time. Of course you could j
ust
use a good C compiler and get this done automagically for you...
Cheers, Clyde
--
Clyde Smith-Stubbs | HI-TECH Software
Email: spam_OUTclydeTakeThisOuT
htsoft.com | Phone Fax
WWW: http://www.htsoft.com/ | USA: (408) 490 2885 (408) 490 2885
PGP: finger .....clydeKILLspam
@spam@htsoft.com | AUS: +61 7 3354 2411 +61 7 3354 2422
---------------------------------------------------------------------------
HI-TECH C: compiling the real world.
1998\10\14@100750
by
Caisson
|
> Van: Dave Johnson <djohnson
KILLspamSIRIUS.COM>
> Aan: .....PICLISTKILLspam
.....MITVMA.MIT.EDU
> Onderwerp: Switch statements (was: Odd PCL behaviour on 16C84)
> Datum: dinsdag 13 oktober 1998 16:57
>
> Is this a "standard" way to do switch statements, by messing with the
> PCL? I've been wondering about this. If the set of things you're
> switching on is consecutive, it seems a jump table arrangement would be
> good, but what if they're not? In my case, I need to switch on various
> non-consecutive ASCII characters. Currently I'm doing something like
this:
[Snip]
> Is this reasonable? Brain dead? Suggestions/comments are welcome.
I think that what you did was one of the best solutions for the problem,
given the controller you are working with (A somewhat restricted type).
You could have "searched" thru a table and used the index of the found char
as an index into a Jump-table, but this would be wasting space in something
like a 16?84 (or others with the same amount of memory for that matter).
Both tables together would take 3 bytes (1 for the char, and 2 for the
subroutine-adress) per "case" (not including the Check & Indexed-jump
routines). Your solution uses 4 bytes per "case" The difference is noth
worth it on the moment. You could shave of a byte per "case" by
subtracting only the difference with the last "comparision". This would
cause a stale-mate between the two (if we forget the surrounding code used
to access both tables).
Assume : W contains the current option
Test:
sublw '?' ;Check first choice
btfss STATUS,Z ;Branch to next check if not equal
goto Test2 ;/
-- Do stuff #1 --
return
Test2:
sublw '!'-'?' ;Subtract difference between "!" and "?" to
;check for the "!" char
btfss STATUS,Z ;Branch to next check if not equal
goto Test3 ;/
-- Do stuff #2 --
return
Test3:
etc, etc, etc ... (quoted from "the king of siam" :-)
Greetings,
Rudy Wieser
1998\10\14@101744
by
Francis.Dupont
|
Dave Johnson wrote:
>
> I use gotos to call the individual routines, with return statements at
> the ends of those routines, so that once they're done they return to
> wherever dispatch was called from. This lets me skip all the other tests
> once I've found a valid case.
>
> Is this reasonable? Brain dead? Suggestions/comments are welcome.
>
> Dave Johnson
--
Hello Dave,
As you require some comments, here are some ideas. If fact nothing
new under the sun, only better 'R E A D A B I L I T Y'. Hi!
My purpose is to have a one page (max) main program in a pseudo
high level language. So I use macros, macros and macros...
Some general rules ( of course there are exceptions) before reading:
- Each identifier beginning with a capital letter, belongs to me
(Constant, Variable, Label, Macro, Subroutine).
- Only basic mnemonics are in lower-case letters.
- In each case (except first), it's possible to avoid reloading w
before testing, but I prefer 'straight programming'. Nobody is perfect.
Here is an example from one programm (serial DDS synthesizer):
;__________________________________________________________________________
;__________________________________________________________________________
;
; MAIN PROGRAM
;__________________________________________________________________________
;__________________________________________________________________________
noexpand
Main
Init
Loop ; Loop
FrequencyChange? ; Update frequency if need
WaitNewCommand ; Get command on serialline
CaseOf ; Case Of
Case1 ; . Command = Frequency
input
Case2 ; . Command = Up
Case3 ; . Command = Down
Case4 ; . Command = Band change
Otherwise ; . Otherwise ERROR
EndCase ; End Case
Forever ; Forever
; (In fact with my assembler, macros must be defined before main.)
;__________________________________________________________________________
;
; MACROS (First level)
;__________________________________________________________________________
Case1 macro
local NextCase
movf NewCommand,w ; Case Of command = 'F'
xorlw 'F'
JNZ NextCase
FrequencyInput ; Get frequency string
goto EndCase
NextCase ;
endm
;--------------------------------------------------------------------------
Case2 macro
local NextCase
movf NewCommand,w ; Case Of command = '+'
xorlw '+'
JNZ NextCase
call FreqInc ; Frequency Up
goto EndCase
NextCase
endm
;--------------------------------------------------------------------------
Case3 macro
local NextCase
movf NewCommand,w ; Case Of command = '-'
xorlw '-'
JNZ NextCase
call FreqDec ; Frequency Down
goto EndCase
NextCase
endm
;--------------------------------------------------------------------------
Case4 macro
local NextCase
movf NewCommand,w ; Case Of command = 'B'
xorlw 'B'
JNZ NextCase
GetBand ; Band change
call BandChange
goto EndCase
NextCase
endm
;--------------------------------------------------------------------------
Otherwise macro
Beep ; Command does not match, so
beep
endm
;__________________________________________________________________________
; Other macros ....
;JNZ is a better way to write: btfss STATUS,Z
; goto address
; and so one...
;__________________________________________________________________________
Of course to add one case all you have to do is to:
- Insert a new line in main
- Copy one case macro to get the structure, paste it and change
what must be changed.
- If you needs several CaseOf in your program, you have to number
them.
(My assembler does not allow local labels, except inside a macro. It's a
pity!)
Any comments?
Francis
-----------------------------------------------------------
Francis DUPONT
F6HSI GQRP # 3553
E-mail : EraseMEFrancis.Dupontspam_OUT
TakeThisOuTuniv-lille1.fr
-----------------------------------------------------------
1998\10\14@200219
by
Regulus Berdin
For readability, one could write a jump if equal macro:
JIFEQ MACRO register,literal,address
movlw literal
xorwf register,w
skpnz
goto address
ENDM
switch:
JIFEQ data,'A',Process_A
JIFEQ data,'B',Process_B
JIFEQ data,'C',Process_C
.
.
.
process_A:
...
return
process_B:
...
return
process_C:
...
return
.
.
.
Reggie
1998\10\15@023427
by
Francis.Dupont
|
Regulus Berdin wrote:
{Quote hidden}>
> For readability, one could write a jump if equal macro:
>
> JIFEQ MACRO register,literal,address
> movlw literal
> xorwf register,w
> skpnz
> goto address
> ENDM
>
> switch:
> JIFEQ data,'A',Process_A
> JIFEQ data,'B',Process_B
> JIFEQ data,'C',Process_C
>
> process_A:
> ...
> return
>
--
This idea seems quite good, except for calling one process.
- You must replace goto address by call address
But when you return, as you have no EXIT, you make the remaining
tests.
No problem, only time consuming.
OR
- You replace each return by a goto EndSwitch. No unnecessary tests
are done,
so it's very fast, and you save one stack location which is
sometimes useful.
Don't forget some form of Otherwise before the EndSwitch. It's a
good security!
Cheers
-----------------------------------------------------------
Francis DUPONT
F6HSI GQRP # 3553
E-mail : Francis.Dupont
spam_OUTuniv-lille1.fr
-----------------------------------------------------------
More... (looser matching)
- Last day of these posts
- In 1998
, 1999 only
- Today
- New search...