Micro Vibe

My Micro Hobby Projects

  • Increase font size
  • Default font size
  • Decrease font size
Home MV4th Forth Documents The COG-EX Forth Word

The COG-EX Forth Word

This article explains the use and implementation of the forth word, COG-EX. The word COG-EX was added to the dictionary starting with version 0.93 of MV4th16.The COG-EX word is intended to simplify the use of a secondary COG to implement forth words.
The interface between the COG running MV4th16 forth and a second COG running some extension software is implemented using a single 4 byte long global memory location. The address of the long memory location is passed to the second COG at startup using the PAR register. Thus the memory address must be long aligned.
The upper 16 bits of the memory location is used to pass the current forth stack pointer address, and the lower 16 bits contains a command index to be executed by the second COG. A non zero value for the command index indicates a command waiting to be executed.
When the COG running MV4th16 forth calls a function in another COG, the current stack pointer and command index are written to the shared long memory location. All parameters are passed to the called function on the forth stack. The called function returns the results on the forth stack. When the called function completes the new stack pointer value is written back to the shared memory location setting the command index to 0 to let the COG running MV4th16 forth know the function has completed. The new value for the stack pointer is loaded from the shared memory location to update the forth data stack.
The syntax of the forth word is:  COG-EX ( uMemAdr uCmdIdx -- ) 
Where:  uMemAdr = address of shared long memory location.  uCmdIdx = 16 bit command index to execute.
The following code snippet shows the code required to implement the COG-EX interface in a COG. The code was taken from the CogPins.spin example file included in the CogPins example folder. See the CogPins.forth file for an example of using the COG-EX forth word.
'*********************************[ FORTH system command support routines]*********************************
' Variables used by forth SYSTEMEX interface
ForthTmp                long    0
ForthCmd                long    0
ForthStackPtr           long    0
ForthScratch            long    0  
' Constants
ForthWordMask           long    $FFFF

' Remove top 16 bit value from forth stack.T1 = 16 bit value on return
                        'make sure we are in a command and stack pointer is valid
F_PopStack              tjz     ForthStackPtr, #F_PopStack_Ret
                        'We are in a command OK to pop value from stack
                        rdword  ForthTmp, ForthStackPtr
                        add     ForthStackPtr, #2
F_PopStack_Ret          ret            
' Add 16 bit value to top of forth stack.T1 = 16 bit value to write.
                        'make sure we are in a command and stack pointer is valid
F_PushStack             tjz     ForthStackPtr, #F_PushStack_Ret
                        'We are in a command OK to push a value to the stack
                        sub     ForthStackPtr, #2
                        wrword  ForthTmp, ForthStackPtr
F_PushStack_Ret         ret            
'Pop a 32 bit value from the forth stack in Low word high word order.
                       'Read High 16 bits from the stack
F_PopStack32            call    #F_PopStack
                        mov     ForthScratch, ForthTmp
                        shl     ForthScratch, #16
                        'Read low 16 bits from stack
                        call    #F_PopStack
                        or      ForthTmp, ForthScratch
F_PopStack32_ret        ret
'Push a 32 bit value to the stack in Low word high word order.
                       'write low 16 bits to stack
F_PushStack32           call    #F_PushStack
                        'write high 16 bits to stack
                        shr     ForthTmp, #16
                        call    #F_PushStack
F_PushStack32_ret       ret
'Wait for a system command to be requested by forth engine
F_WaitForCmd            rdlong  ForthCmd, par
                        test    ForthCmd, ForthWordMask  wz
        if_z            jmp     #F_WaitForCmd
                        'Seperate stack address from command number
                        mov     ForthStackPtr, ForthCmd
                        shr     ForthStackPtr, #16
                        and     ForthCmd, ForthWordMask
                        'see if we have a valid command
                        cmp     ForthCmd, #c_ForthCmdCount                      wc
        if_c            jmp     #F_WaitForCmd_ret
                        ' we have an invalid command
                        call    #F_CompleteCommand                       
                        jmp     #F_WaitForCmd
                        ' we have a valid command, get the stack pointer address
F_WaitForCmd_Ret        ret
'Update stack pointer then exit
F_SaveStackptr          mov     ForthTmp, par
                        add     ForthTmp, #2
                        wrword  ForthStackPtr, ForthTmp
'Indicate system command requested by forth engine is completed
F_CompleteCommand       mov     ForthCmd, #0                         
                        wrword  ForthCmd, par
                        mov     ForthStackPtr, #0
F_CompleteCommand_ret   ret
'Wait for a command and execute it
F_Do_Cmds               call    #F_WaitForCmd
                        'we have a cmd index 1..XX
                        mov     ForthTmp, #F_JUMP_TABLE
                        add     ForthTmp, ForthCmd
                        movs    :F_Set_Cmd_Jump, ForthTmp
:F_Set_Cmd_Jump         mov     :F_Do_Cmd_Jump, (ForthTmp)
:F_Do_Cmd_Jump          nop
                        'The called function will return here
F_Do_Cmds_Return        call    #F_SaveStackptr
                        jmp     #F_Do_Cmds
'Table of Jump opcodes for each of the supported forth functions
F_JUMP_TABLE            nop                             '(0)
                        call    #F_CMD_RdIna            '(1)
                        call    #F_CMD_RdOuta           '(2)
' *********************************[ Forth Commands ]*********************************
' 1)  Read the I/O pins input register ina@ ( -- dAllPins )
F_CMD_RdIna             mov     ForthTmp, INA
                        call    #F_PushStack32
F_CMD_RdIna_ret         ret
' 2)  Read the I/O pins output register
' outa@ ( -- dRegValue )
F_CMD_RdOuta            mov     ForthTmp, OUTA
                        call    #F_PushStack32
F_CMD_RdOuta_ret        ret                       
Last Updated on Tuesday, 27 November 2012 11:05