WS2812 pixel processing extensions

There may be some reason why the WS2812_Command System Function needs to be replaced by a different subroutine. That can accomplished by intercepting the WS2812_Command and executing an alternate subroutine in FLASH and specifying a pointer in EEPROM to it.

This is how both the WS2812_Command and the WS2812_Cmd_PortSet System Functions implement the WS2812 extension:
AHi_EEPointer = EEfptrWS2812Exts >> 8
ALo_EEPointer = EEfptrWS2812Exts & 0xFF

   MOVW    R30, R20           ; Point 'Z' at the PORT's SRAM address
   MOVW    R26, R24           ; Move the data buffer pointer in R25:R24 to 'X'
   LDI     R25, AHi_EEPointer ; Load the pointer in EEPROM to a pointer in
   LDI     R24, ALo_EEPointer ;  FLASH memory and let the system routine 
   CALL    AICALL_IfValid_EEPROM      ; determine what to do next
   BRNE    AWS2812_Return     ; If it returns "Its been handled", we're done

;      ...                    ; Continue executing the original logic

WS2812_Ret:
   RET
                                                                                            
The ICALL_IfValid_EEPROM System Function will only call the extension if the WORD pointer (i.e., FLASH address) at the EEPROM address specified, (which, in this case, is 78 or 0x4E, based on EEfptrWS2812Exts) points to a WORD in FLASH memory that is neither 0 or 0xFFFF. If the pointer in EEPROM points to an invalid EEPROM address (like 0xFFFF) it will exit. If the EEPROM pointer is valid and either of the two (2) conditions above are true, it will consider the FLASH to be uninitialized and will skip the CALL to the Extension subroutine.

Stated another way, the pointer in EEPROM must be valid and point to an initialized subroutine address in FLASH memory for the Extension to be CALLed.

All five (5) extensions work the same way upon return. If the ZERO FLAG is CLEAR, it handled the request and the original code should be skipped. If the ZERO flag is SET, the original Operating System code should be executed with the Registers configured appropriately upon return. This usually means that the Registers are returned with the same values they had when the extension logic was called. It is also possible, however, that only a Register change or command line change needed to be made by the extension and processing by the original logic can continue with those changes.