High4BitsToPORT  and  Low4BitsToPORT

Purpose: Convert 4 of the BITs in R24 to the SRAM address of a PORT.
Assumes:   For High4BitsToPORT, the BITs of interest in R24 are B1111####, or 0xF0
For Low4BitsToPORT, the BITs of interest in R24 are B####1111, or 0x0F
    where # means don't care about those bit states (i.e., discarded)
Passed: R24 BYTE bSelect BIT pattern selecting a PORT; for a 328P: B0001 = PORTB, B0010 = PORTC, B0011 = PORTD
Returns: R25:R24   WORD   bPORTinSRAM   SRAM address of the PORT, e.g., PORTB = 0x25, PORTC = 0x28, PORTD = 0x2B
Z FLAG   BIT_ZERO   CLEAR (0 or FALSE) if valid, SET (1 or TRUE) if invalid
Alters: Only R24, R25, and the FLAGs (SREG)
Notes: For a 328PB, B0100 validly selects PORTE; for a 1284P, B0000 validly selects PORTA

Low3BitsToBitmask

Purpose: Convert the 3 Least Significant BITs into a value 0 through 7
Assumes:   The selector is in B#####111, where # means don't care about those bit states (i.e., discarded)
Passed: R24 BYTE bSelect three (3) LSBits select precisely one bit in the eight (8)
Returns: R24   BYTE   bBitmask   bitmask with precisely one (1) bit set
Alters: Only R24 and the FLAGs (SREG)
Notes: B000 selects bitmask B00000001, B001 selects bitmask B00000010,
B010 selects bitmask B00000100, B011 selects bitmask B00001000,
B100 selects bitmask B00010000, B101 selects bitmask B00100000,
B110 selects bitmask B01000000, and B111 selects bitmask B10000000

Example:  
Demo_DiscreteOutput:
   MOV     R23, R24                ; Save the caller's PORT and PINS in R23
   CALL    AHigh4BitsToPORT        ; Returns an indirect pointer (PORT + 32)
   BREQ    ALocalRet               ; If the ZERO FLAG is set, it's invalid

   MOVW    R30, R24                ; Set 'Z' = PORT address WORD returned
   MOV     R24, R23                ; Restore the caller's PORT and PINs value
   CALL    ALow3BitsToBitmask      ; Convert 0-7 index to B######## bitmask
   SBRC    R23, 3                  ; If the PORT/PIN variable has B00001000
   SBIW    R30, 2                  ;  set, switch from PORT# to PIN# register
   LD      R25, Z                  ; Read the present 8-bit BYTE value
   CPI     R22, 0                  ; Set the ZERO flag if R22 is equal 0; if
   BREQ    ATurnOFF                ;  so, jump past the TurnON logic

TurnON:
   OR      R25, R24                ; Combine in the new bit (bitmask in R24)
   RJMP    AWriteDO                ;  with value just read (in R25) and jump

TurnOFF:
   COM     R24                     ; Flip all bits in R24 (1's complement) to
   AND     R25, R24                ;  mask OFF the corresponding bit in R25

WriteDO:
   ST      Z, R25                  ; Save the WORD value back to the PORT

LocalRet:
   RET
Notes: Ten (10) System Configuration BYTEs in EEPROM use a single BYTE to specify both a single output PORT and PIN. They are used by the Operating System to automatically update some output based on a particular state or status input or to select an invalid output (e.g., 0xFF), thereby disabling that status from being displayed in any LED or output. Each is generally expected to specify a Discrete (or LED) output on PORTC, but may be configured to use another PORT and PIN. The definitions below are all contained in the SystemEEPROM.Def file.
Name Address Usage Default Value    Notes
EEbWS2812_DefPandP   12 = 0x0C   Default WS2712 Port & (single) Pin> B00101000 = 0x28 PORTC, but bit 0x08 set means use multiple bits
EEbLED_Awake 24 = 0x18 OFF when in sleep mode; ON when running  0xFF (none)
EEbLED_Heartbeat 25 = 0x19 Switches state once each second B00100101 = 0x25 PORTC, PINC6
EEbLED_IRQ0 26 = 0x1A nRF radio (IRQ0) interrupt input status 0xFF (none)
EEbLED_IRQ1 27 = 0x1B Alarm Input (IRQ1) status 0xFF (none)
EEbLED_PinCE 28 = 0x1C nRF radio Chip Enable status 0xFF (none)
EEbLED_RPDInd 29 = 0x1D nRF radio REG_9_RPD status 0xFF (none)
EEbLED_TxInd 30 = 0x1E nRF radio in Transmit mode 0xFF (none)
EEbLED_PwrUp 31 = 0x1F nRF radio Register 0 PWR_UP bit status 0xFF (none)
EEbLED_LoginStatus 32 = 0x20 When in either Manager or Admin mode B00100100 = 0x24 PORTC, PINC5
Dropin: 
(setup
code)
;   Setup for the High4BitsToPORT() call:
; Passed:      R24 BYTE bSelectBits   328P: 0x10 (PORTB) to 0x30 (PORTD)
; Returns: R25:R24 WORD wSRAMAddress  0x0025, 0x0028, 0x002C or 0 (for a 328P)
;              'Z' FLAG CLEAR if valid, SET if invalid (when R25:R24 is 0)
; Alters:  R24, R25, and the FLAGs

;   Setup for the Low4BitsToPORT() call:
; Passed:      R24 BYTE bSelectBits   328P: 1 (PORTB), 2 (PORTC), or 3 (PORTD)
; Returns: R25:R24 WORD wSRAMAddress  0x0025, 0x0028, 0x002C or 0 (for a 328P)
;              'Z' FLAG CLEAR if valid, SET if invalid (when R25:R24 is 0)
; Alters:  R24, R25, and the FLAGs

;   Setup for the Low3BitsToBitmask() call:
; Passed:  R24 BYTE bSelect with only the three (3) Least Significant BITs used
; Returns: R24 BYTE bBitmask with precisely one (1) BIT set in the BYTE
; Alters:  R24 and the FLAGs
Also see:  The WS2812_Command and WS2812_Cmd_PortSet System Functions as well as the WS2812 example code.