Short of resorting to inline ASM and potentially having to deal with bank issues, etc., I put together the suggestions here on this thread and ran the execution tests.
I captured the results in the table below.

Here is the code that I used to test with.
Code:
'****************************************************************
'* Name : NCDTest.pbp *
'* Author : TABSoft *
'* Notice : Copyright (c) 2015 TABSoft *
'* : All Rights Reserved *
'* Date : 3/3/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
'*****PIC MCU Configuration Fuses (MPASM)*****
#IF __PROCESSOR__ = "18F4620"
#CONFIG
CONFIG OSC = ECIO6 ; EC oscillator, port function on RA6
;CONFIG OSC = INTIO67 ; Internal oscillator block, port function on RA6 and RA7
;CONFIG WDT = OFF ; WDT disabled (control is placed on the SWDTEN bit)
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor disabled
CONFIG IESO = OFF ; Oscillator Switchover mode disabled
CONFIG PWRT = OFF ; PWRT disabled
CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
CONFIG BORV = 3 ; Minimum setting
CONFIG WDT = ON ; WDT enabled
CONFIG WDTPS = 512 ; 1:512
CONFIG CCP2MX = PORTC ; CCP2 input/output is multiplexed with RC1
CONFIG PBADEN = OFF ; PORTB<4:0> pins are configured as digital I/O on Reset
CONFIG LPT1OSC = OFF ; Timer1 configured for higher power operation
CONFIG MCLRE = ON ; MCLR pin enabled; RE3 input pin disabled
CONFIG STVREN = ON ; Stack full/underflow will cause Reset
CONFIG LVP = OFF ; Single-Supply ICSP disabled
CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
CONFIG DEBUG = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
CONFIG CP0 = OFF ; Block 0 (000800-003FFFh) not code-protected
CONFIG CP1 = OFF ; Block 1 (004000-007FFFh) not code-protected
CONFIG CP2 = OFF ; Block 2 (008000-00BFFFh) not code-protected
CONFIG CP3 = OFF ; Block 3 (00C000-00FFFFh) not code-protected
CONFIG CPB = OFF ; Boot block (000000-0007FFh) not code-protected
CONFIG CPD = OFF ; Data EEPROM not code-protected
CONFIG WRT0 = OFF ; Block 0 (000800-003FFFh) not write-protected
CONFIG WRT1 = OFF ; Block 1 (004000-007FFFh) not write-protected
CONFIG WRT2 = OFF ; Block 2 (008000-00BFFFh) not write-protected
CONFIG WRT3 = OFF ; Block 3 (00C000-00FFFFh) not write-protected
CONFIG WRTC = OFF ; Configuration registers (300000-3000FFh) not write-protected
CONFIG WRTB = OFF ; Boot Block (000000-0007FFh) not write-protected
CONFIG WRTD = OFF ; Data EEPROM not write-protected
CONFIG EBTR0 = OFF ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
CONFIG EBTR1 = OFF ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
CONFIG EBTR2 = OFF ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
CONFIG EBTR3 = OFF ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
CONFIG EBTRB = OFF ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
#ENDCONFIG
#else
#ERROR "This program requires a PIC 18F4620 MCU"
#endif
OSCCON = $60 ' Set PIC to 4Mhz & ECIO Clock Mode
DEFINE OSC 4
ADCON0.0 = 0 ' A/D Converter module is disabled
ADCON1 = $0F ' %0000 1111 AN2=VSS, AN3=VDD, AN12-0 = Digital
ADCON2 = $00 ' %0000 0000
TRISB = %11111111 ' Set PORTB as input
INTCON2.7 = 0 ' Enable PORTB pullups
TRISC = TRISC & %11011111 ' Set PORTC pin directions (pin5 output to RTC VCC2)
i var byte
mybyte var byte
mystatus var byte
workword var word
workbyte var workword.byte0 ' 1st byte
bitcarry var workword.8 ' 9th bit
bitcount var byte
bytArray var byte[9]
bytArray[0] = 0
bytArray[1] = 1
bytArray[2] = 2
bytArray[3] = 4
bytArray[4] = 8
bytArray[5] = 16
bytArray[6] = 32
bytArray[7] = 64
bytArray[8] = 128
'*****Define LCD registers and bits*****
define LCD_BITS 4
define LCD_LINES 2 ' Set to number of lines for the LCD
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
define LCD_RWREG PORTE
define LCD_RWBIT 2
define LCD_COMMANDUS 1500
define LCD_DATAUS 44
'*****Initialize LCD*****
Low LATE.2 ' LCD R/W line low (W)
Pause 500 ' Wait .5 second for LCD to Initialize
mainloop:
do
for i = 0 to 8
workword.byte1 = 0
workbyte = bytArray[i]
gosub NCD8
next i
for i = 0 to 8
workword.byte1 = 0
workbyte = bytArray[i]
gosub NEWNCD8
next i
for i = 0 to 8
mystatus = bytArray[i]
gosub checkbit8
next i
for i = 0 to 8
mystatus = bytArray[i]
gosub checkbit8ztest
next i
for i = 0 to 8
mystatus = bytArray[i]
gosub NCDSUB
next i
for i = 0 to 8
mystatus = bytArray[i]
gosub LOOKSUB
next i
pause 500
loop
NCD8:
' Input: workword (including workbyte)
'Return: bitcount
'Locals: bitcarry
' Notes: If workbyte = 0 then bitcount is set to 0
' otherwise bitcount = bitnumber (0-7)
bitcount = 8 ' mov l to w & w to f
if workbyte = 0 then ' portX was zero
bitcount = 0
return
endif
inloop:
bitcount = bitcount - 1 ' decf
workword = workword << 1 ' 2 x rrf with carry
if bitcarry = 0 then 'btfss
goto inloop ' goto
endif
return
NEWNCD8:
' Input: workword (including workbyte)
'Return: bitcount
'Locals: bitcarry
' Notes: If workbyte = 0 then bitcount is set to 0
' otherwise bitcount = bitnumber (0-7)
if workbyte = 0 then 'portX was zero
bitcount = 0
return
endif
bitcount = 8
do
bitcount = bitcount - 1
workword = workword << 1
loop while bitcarry = 0
return
checkbit8:
' Input: mystatus
'Return: bitcount
'Locals: none (direct bittest of mystatus
' Notes: If mystatus = 0 then bitcount is not changed
' otherwise bitcount = bitnumber (0-7) (can be changed to any byte value)
if mystatus.7 = 1 then
bitcount = 7
return
endif
if mystatus.6 = 1 then
bitcount = 6
return
endif
if mystatus.5 = 1 then
bitcount = 5
return
endif
if mystatus.4 = 1 then
bitcount = 4
return
endif
if mystatus.3 = 1 then
bitcount = 3
return
endif
if mystatus.2 = 1 then
bitcount = 2
return
endif
if mystatus.1 = 1 then
bitcount = 1
return
endif
if mystatus.0 = 1 then
bitcount = 0
return
endif
return
checkbit8ztest:
' Input: mystatus
'Return: bitcount
'Locals: none (direct bittest of mystatus)
' Notes: If mystatus = 0 then bitcount is not changed (can be changed to any byte value)
' otherwise bitcount = bitnumber (0-7) (can be changed to any byte value)
if mystatus = 0 then
return
endif
if mystatus.7 = 1 then
bitcount = 7
return
endif
if mystatus.6 = 1 then
bitcount = 6
return
endif
if mystatus.5 = 1 then
bitcount = 5
return
endif
if mystatus.4 = 1 then
bitcount = 4
return
endif
if mystatus.3 = 1 then
bitcount = 3
return
endif
if mystatus.2 = 1 then
bitcount = 2
return
endif
if mystatus.1 = 1 then
bitcount = 1
return
endif
if mystatus.0 = 1 then
bitcount = 0
return
endif
return
NCDSUB:
' Input: mystatus
'Return: mybyte
'Locals: none (direct bittest of mystatus)
' Notes: If mystatus = 0 then mybyte is not changed
' otherwise mybyte = bitnumber (1-8)
mybyte = NCD mystatus
return
LOOKSUB:
' Input: mystatus
'Return: mybyte
'Locals: none (direct bittest of mystatus)
' Notes: If mystatus = 0 then mybyte set to 0
' otherwise mybyte = bitnumber (1-8)
lookdown2 mystatus, <= [%00000000, %00000001, %00000011, %00000111, %00001111, %00011111, %00111111, %01111111, %11111111], mybyte
return
end
Bookmarks