Tom Hartman says:
...I came up with a method for a "switch" statement, its a little faster than average because it doesn't reload the variable for each case. Each case is 3 clocks if not equal, 4 clocks if equal. Code can appear between cases, but be careful not to alter the contents of w.; Switch, case macros: ; Typical usage: ; #define CONSTANT1 1 ; #define CONSTANT2 2 ; SWITCH_F file_register ; CASE_W CONSTANT1, do_case_1 ; CASE_W CONSTANT2, do_case_2 ; ; --- Or where W is already the variable--- ; SWITCH_W ; CASE_W CONSTANT1, do_case_1 ; CASE_W CONSTANT2, do_case_2 ;-------------- SWITCH_W macro _previous_case set 0 ; W already contains the switch variable endm ;-------------- SWITCH_F macro f_label mov W, f_label ; read the location into w _previous_case set 0 endm ;-------------- CASE_W macro case_const, case_label xor W, #case_const^_previous_case snb Z jmp case_label _previous_case set case_const endm ;------------------------------------------------------------------
Rich Leggitt says:
...I thought of a way to cut 'switch' to one instruction, it ain't gonna get any smaller than that :)switch macro retw #$+1 ; return 'return' endm context equ $20 mov W, #task1 ; note task 1 will run first mov context, W mov W, #task2 ; task switcher call $+2 ; make a place for 'switch' to return to jmp $-1 ; (i.e. here!) xor context, W ; then exchange w and context xor W, context xor context, W mov PC, W ; and jmp to w task1 blah switch etc switch stuff jmp task1 task2 asdf switch zxcz jmp task2
to which Scott Dattalo commented:Cool! Now that you write this, I recall someone else (I believe it was Payson) doing something similar. Now that you've got the 'context switching' all confined to one section, you've opened up the possibilities of extending its functionality (without having duplicate code snippets scattered throughout).
- ) You could easily add additional tasks. Cycling through each can be done in a 'round-robin' fashion. For example, after task A then run task B, C,..., N, and back to A.
- ) You could add priorities to the tasks.
- ) With an extra instruction in the 'switch' macro, you could handle multiple pages:switch macro mov W, #HIGH($+2) retw #$+1 endm -----------------------
If you're using the 12bit core, then you might consider populating the stack with the address of the context switcher. You could do the same with the 14bit core - but chances are you're more likely to need the stack for making calls. (on the 12bit core, the stack is only 2 levels ) Once the stack is filled, then the retlw's will take advantage of stack roll overs.mov W, #task1 mov context, W mov W, #task2 setb C clr first_time jmp l2 l1 rl first_time sb first_time.1 l2 call l1 l3 xor W, #context ; then exchange w and context xor W, #context xor W, #context mov PC, W ; and jmp to w
for the 14bit core you could fill the stack:mov W, #task1 mov context, W mov W, #task2 setb C clr first_time jmp l2 l1 rl first_time sb first_time.7 l2 call l1 l3 xor W, #context ; then exchange w and context xor W, #context xor W, #context mov PC, W ; and jmp to w
I haven't tried this, but once you get the stack 'primed', you can save 4 execution cycles.
|file: /Techref/scenix/lib/flow/swstmt_sx.htm, 4KB, , updated: 2006/11/28 12:23, local time: 2022/9/27 20:41,
|©2022 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?|
<A HREF="http://massmind.org/techref/scenix/lib/flow/swstmt_sx.htm"> scenix lib flow swstmt_sx</A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to massmind.org!