C3 SPI Drivers - part 1 ( setup )

Now we can setup the routine that will pass commands to the memory location shared with the assembly section. 

This routine will be declared as private to leave its use to this driver only.

PRI
 setcommand( cmd, argptr ) 
   command := cmd << 16 + argptr 
   repeat while command
 
Then our first driver "command" 

PUB SPI_Init 
   setcommand( _spiInit, 0 )
 
This routine will make the setcommand store the value of _spiInit ( 1 ) into the shared memory, that will be read by the entry routine in the assembly section. 

DAT org
 

entry       rdlong t1,par          wz  ' retrieve parameters from the caller 
       if_z jmp    #entry              ' if no parameter loop in waiting for parameters
            movd   :arg, #arg0         ' use the pointer to a local variable arg0 as 
                                       ' destination 
                                       ' for instruction at label :arg
            mov    t2, t1              ' setup the cycle for reading parameters from the caller
            mov    t3, #3              ' 3 parameters for the cycle

:arg        rdlong arg0, t2            ' reads the parameter at t2
            add    :arg, d0            ' increment position of destination by d0 
            add    t2, #4              ' increment position of source pointer 
            djnz   t3, #:arg           ' decrease parameter counter and jumps to :arg if not 
                                       ' zero
            mov    parameters, t1      ' keeps the pointer to parameters for later use

            wrlong zero,par            ' this sends 0 to par pointer, ( command ) and the spin 
                                       ' routine 
                                       ' and will read it = 0. This will exit setcommand SPIN 
                                       ' routine 

            ror    t1, #16+2           ' align the value of parameter to retrieve the command 
                                       ' value 
            add    t1, #jumps          ' add the pointer to jumps table to the command value
                                       ' so the command 1 will point to jumps + 1 long, command 
                                       ' 2 to jumps +2 etc...
            movs   :table, t1          ' setup this pointer as a source pointer for :table 
                                       ' instruction 
            rol    t1, #2        
            shl    t1, #3
:table      mov    t2, 0               ' retrieve the pointer location of the label 
                                       ' corresponding to the command 
            shr    t2, t1
            and    t2, #$FF
            jmp    t2                  ' and jump to it 

jumps       byte   $0 
            byte   _spi_init
            byte   _spi_set_ch 
            byte   _spi_wr
            byte   _spi_rd

NotUsed_    jmp    #loop               ' go on with loop 
 
This is a common template to for creating a command driven routines libary.