*************************** HeliOS MOVER motor routines *************************** ************ Introduction ************ The HeliOS Mover routines are part of the interrupt-driven game operating system and function as one of the HeliOS "motor" routines. These are fast optimised machine coded routines which can be controlled entirely by pre-defined data structures. These functions only work in HeliOS mode. HeliOS Mover functions allow fast and efficient performance of simple data table transfers synchronously with other functions performed by the interrupt driven HeliOS system. Movers are designed to allow data items to be copied from one location to another, with optional negation, or to store zero values. These Mover functions allow interactions between data structures to be set up which will run fully automatically in the background. Using pre-defined control data structures, along with direct programmability if required, you can generate a number of different limiting functions. These routines have many applications, in particular they allow mutual control between events occurring in different sub-systems. It is impossible to list all the possible ways of using these highly flexible routines, and it will be easier to see the potential of this system after examining how it works. It is worth pointing out that all HeliOS motor functions are not only pre-programmable, but they operate in a mutually self-programming way by allowing "modifiers" and "results" to operate on other motors. In other words input and output from motor programs do not only work with parameters stored in their own "private" data structures: motors can also read inputs and distribute results by interacting with control data structure fields of other motors or any other computed objects. This INDIRECTION of input and output, a feature common to ALL HeliOS data objects, allows complex interlinking and self-programmability. The mutual self-programmability of HeliOS objects means that the results of one operation can be used to automatically program another, which in turn can (re)act on the first....and so on. All this can be set up to work automatically without you having to do any intermediate programming to manage all the interactions. This means, in other words, that all HeliOS motors can PROGRAM EACH OTHER, so input or output data can be modified by other motor functions and can in turn program other motors. This mutual programmability combined with the BEFORE and AFTER functions give the HeliOS motor functions considerable power from ultra fast and very simple routines. ****** Timing ****** It is an important consideration that all motor functions are fully synchronised with all other HeliOS internally automated functions and with the display frame rate. Motors are run in the order in which they are installed: you must remember this if you are using one motor function to modify another. ****************** Control structures ****************** The main Mover control structure is as follows: ------------------------- Mover control structure ------------------------- Mover_BeforeForth(w) = HeliOS CFA to run BEFORE each Mover calculation Mover_BeforeCode(l) = Machine code to run BEFORE each Mover calculation Mover_AfterForth(w) = HeliOS CFA to run AFTER each Mover calculation Mover_AfterCode(l) = Machine code to run AFTER each Mover calculation Mover_Flags(w) = Control flags word ( See below) Mover_CountDown(w) = Countdown time (If non-zero sets countdown) Mover_CDFlags(w) = Countdown flags word (-> "Flags" at CountDown time) Mover_CDForth(w) = Countdown HeliOS function CFA (optional) Mover_CDCode(l) = Countdown machine code function pointer (optional) Mover_SkipTimer(w) = Mover skip internal timer register Mover_SkipCount(w) = Mover skip count = How many "ticks" to skip (0=Do all) Mover_ID(w) = Motor handler ID = 2 for Mover Mover_Count(w) = Number of Mover data blocks Mover_Data(l) = Mover data list pointer Mover_UserDataPtr(l) = Free user data pointer Mover_UserData1(w) = Free user data1 Mover_UserData2(w) = Free user data2 Mover_UserData3(w) = Free user data3 Mover_UserData4(w) = Free user data4 Mover_UserData5(w) = Free user data5 Mover_UserData6(w) = Free user data6 Mover_UserStatus(w) = Free user status Here is an amplified description of each field: Mover_BeforeForth This field, if non-null, contains the CFA af a HeliOS command which will be run BEFORE each iteration of the Mover function. A 32-bit pointer to the Mover control structure will be placed on the stack when the HeliOS BEFORE command is called, so you must take care to clear the stack. Mover_BeforeCode This field, if non-null, contains a pointer to a machine code routine which will be run BEFORE each iteration of the Mover function. A 32-bit pointer to the Mover control structure will be placed in address register A0 when the BEFORE command code is called. Mover_AfterForth This field, if non-null, contains the CFA af a HeliOS command which will be run AFTER each iteration of the Mover function. A 32-bit pointer to the Mover control structure will be placed on the stack when the HeliOS AFTER command is called, so you must take care to clear the stack. Mover_AfterCode This field, if non-null, contains a pointer to a machine code routine which will be run AFTER each iteration of the Mover function. A 32-bit pointer to the Mover control structure will be placed in address register A0 when the AFTER command code is called. Mover_Flags This field contains the Mover function control flags. The following function control flags are available: -3 = SelfRemove at once 0 = Skip Mover function "Before" functions still run in "Skip" mode. Mover_CountDown Sets up a CountDown, so that after the number of "ticks" specified in this field the CDFlags value will be stored into the Flags field of the Mover command structure. This function is switched off after each CountDown. Mover_CDFlags If a CountDown is being done, the value in this field will be placed in the "Flags" field of the Mover command structure when the CountDown is complete. Mover_CDForth This field contains either null or the CFA of a HeliOS function which you wish to be executed after CountDown has completed. Mover_CDCode This field contains either null or a pointer to a machine code routine which you wish to be executed after the CountDown has completed. Mover_SkipTimer This field is used to store the internal timer status of the Mover motor. Mover_SkipCount This value gives the time delay between each iteration of the Mover function. The Mover will skip however many "ticks" are specified here between each active cycle. A SkipCount value of "0" gives full speed operation. Mover_ID This MUST be set to "2", to identify the Mover function. Mover_Count The number of data items constituting this Mover. Mover_Data A pointer to the start of the sequence of Mover data structures associated with this control structure, as defined below, each placed one after the other. Each master Mover control structure can drive an unlimited number of individual Movers, each of which has a different data structure. Mover_UserDataPtr This is a "free" field which you can use as you wish. Mover_UserData1 This is a "free" field which you can use as you wish. Mover_UserData2 This is a "free" field which you can use as you wish. Mover_UserData3 This is a "free" field which you can use as you wish. Mover_UserData4 This is a "free" field which you can use as you wish. Mover_UserData5 This is a "free" field which you can use as you wish. Mover_UserData6 This is a "free" field which you can use as you wish. Mover_UserStatus This is a "free" field which you can use as you wish. -------------------- MoverData structure -------------------- MoverData_Source(l) = Pointer to source data start address MoverData_Target(l) = Pointer to target data start address MoverData_Length(w) = Data length of operation MoverData_Modifier(w) = Modifier Here is an amplified description of each field: MoverData_Source(l) This field contains a pointer to the start of an area of memory from which data is to be moved. MoverData_Target(l) This field contains a pointer to the start of an area of memory to which data is to be moved. MoverData_Length(w) This field specifies whether this operation is on 1, 2, or 4 byte values and should be set accordingly to "1", "2", or "4". MoverData_Modifier(w) This field specifies how many "cells" (each of "Length" bytes) are to be copied, and whether the data should be negated or null, as follows: Modifier -> +ve number = Move "n" cells of data. Modifier -> -ve number = Move "n" cells of data negating each data item before storing it. Modifier -> 0 = Move just 1 zero valued cell into target address. (i.e. set target cell = 0) ********************************** HeliOS Mover control command words ********************************** There are NO words specifically to control Mover functions. All control is via the data structures detailed above. Movers are started by using the expression: MyMover INSTALLMOTOR Movers are stopped by using the expression: MyMover REMOVEMOTOR ************** Using Movers ************** Movers are VERY easy to use and to set up. First you need to allocate a master Mover structure: Mover_SIZEOF MAKESTRUCTURE MyMover D! or something similar...... Then you need to allocate at least one Mover data structure: MoverData_SIZEOF MAKESTRUCTURE MyMoverData D! Then you must set up the pointers and data structure values: MyMoverData D@ MyMover D@ Mover_Data INDEXD!L MyMover D@ SETSTRUCTURE1 1 Mover_Count STRUCTURE1 !L 1 Mover_Flags STRUCTURE1 !L 1 Mover_SkipCount STRUCTURE1 !L 2 Mover_ID STRUCTURE1 !L \ Set up Mover to copy 12 bytes of data from Source to Target at each \ iteration of the motor functions. This will cause the target data \ table to be constantly updated from the source data table. CREATEL Source 1 C, 2 C, 3 C, 4 C, 5 C, 6 C, 7 C, 8 C, 9 C, 10 C, 11 C, 12 C, CREATEL Target 12 0 ALLOTFILL MyMoverData D@ SETSTRUCTURE1 Source MoverData_Source STRUCTURE1 D!L Target MoverData_Target STRUCTURE1 D!L 1 MoverData_Length STRUCTURE1 !L 12 MoverData_Modifier STRUCTURE1 !L Then you must use INSTALLMOTOR when you want to start the Mover process: MyMover D@ INSTALLMOTOR ...and REMOVEMOTOR when you want to stop the Mover process: MyMover D@ REMOVEMOTOR ********************************************************************* End *********************************************************************