This is used to synchronize with an external event, with minimal response time.
#define FOREVER for( ; ; ) FOREVER { while( !ready( ) ) ; do-it( ); }
or in another form
FOREVER { if ( ready( ) ) do-it( ); }
From the time that the ready bit sets until the next byte is in the data register
while( !ready( ) )
or if( ready(
) )
_ready: ldb r0, CS-ADDRESS and r0, r0, READY-BIT ret _do-it: stb r1, DATA-ADDRESS inc r3 ldb r1, [r3] // get the next byte ret # _out-str: jsr _ready beq r0, _out-str jsr _do-it br _start
The subroutine would be in-lined but I have omitted that part for clarity.
and
,
beq
, ldb
, and, beq
and
stb
Maybe this isn't fast enough for you. Here's an "improvement", for your amusement
L10000000: nop .... L2: nop L1: nop L0: ldb r0, [r3] // get the next byte inc r3 stb r0, DATA-ADDRESS br r5 // r5 contains the address to which we branch
In the initialization code we determine, by experiment, exactly how many
nops we need in order to land on the stb
instruction just after
the ready bit sets.
NOP
There's a lesson for everybody in this extreme example. (Actually there are more extreme examples, and they are used also.) Wherever there is a nicely structured solution with response time x seconds there is a disgustingly-structured example with reponse time less than x/10.
Polling loops allow you to manage more than one condition/activity pair at the same time.
The basic polling loop
FOREVER { if( c1 ) a1; if( c2 ) a2; ... if( cN ) aN; }
if( c<n>
) + execution time
of a<n>
Suppose you want a better response time for a1. Then try the loop
FOREVER { if( c1 ) a1; if( c2 ) a2; if( c1 ) a1; if( c3 ) a3; ... if( c1 ) a1; if( cN ) aN; }
Worst case response time for a1
if( c1 )
+ \max_n execution time for
if( cn ) an
Suppose the response time is still too long, because the execution of one action, say a2, is too long. Then you can break a2 into two parts
FOREVER { if( c1 ) a1; if( c2 ) { a2.1; half-done = TRUE } if( c1 ) a1; if( half-done ) a2.2; ... }
This is strarting to get a little complicated and we haven't said anything about inter-action communication
We can use interrupts to get rid of polling
Like function calls without arguments or return values.
Contrast RT to non-RT
Return to: