Hi Darrel,
Thanks for all the effort you have put into this. Below is my entire program, using your LCD code. It still does not work - the LCD top line are dark squares and the lower line is all blanks. I tried a different brand of LCD this morning - same story.

I want to use a backlit LCD which draws about 100 mA so I could cut a trace and add a PNP high side switch but I would rather not if a software fix can be found.

The code fuses in the PIC16F877A (set via EPIC) include LVP OFF, WDT ON, BOD ON, POR ON for those asking about LVP.

I need to fully understand what your code does as it looks similar to what I am trying in a sequence of PBP247 lines. Where can I find an explanation of the instructions used in your code? I can make sense of some lines but I don't know what is happening with...

@ MOVE?CT 0, LCD_EREG+80h,LCD_EBIT ; Enable is OUTPUT
Does this OR together the Enable bit with 80 hex?

@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +1
@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +2
@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +3
What does the +1, +2, +3 do?

I do want to end up with a bullet proof LCD startup sequence, preferably all written in PBP, that can reliably work with slow start power supplies. The PIC 16F877A data sheet (parameter D004) shows a PIC can work with power supply dV/dT as low as 50 volts per second (i.e. 100 mS power supply rise time). I want to be sure the LCD will also work in that environment or this problem will bite me again and again in other designs as well.

The full code follows

data @0, 0 'Action Flags
data @1, 0 'Status flags
Data @2, "PW50 Gas Mix LCD fix BDT 19 OCT 06 "


define osc 20
define loader_used 1
Define LCD_DREG PORTD
Define LCD_DBIT 0
Define LCD_RSREG PORTD
Define LCD_RSBIT 5
Define LCD_EREG PORTD
Define LCD_EBIT 4
DEFINE LCD_LINES 2
DEFINE LCD_BITS 4
'DEFINE LCD_COMMANDUS 5000 'Command delay time in us
'DEFINE LCD_DATAUS 250 'Data delay time in us
define char_pacing 200
DEFINE SHIFT_PAUSEUS 500


@ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF

'***************** hardware definition ***********************
'PortA
Function var porta.0 'pin 2 analog from 12 position switch IN
RunStop var porta.1 ' SWp6 to 877p3 Front panel toggle IN
Enter var porta.2 ' SWp4 to 877p4 Selects current value IN
Up var porta.3 ' SWp2 to 877p5 Advances selection IN
AutoMan var porta.4 ' SWp7 to 877p6 Local/Remote control IN
Down var porta.5 ' SWp3 to 877p7 Reduces selection IN
TRISA = %00011111
CMCON = %00000111 ' comparators disabled
ADCON0 = %11000000 ' int RC clock, ADC disabled
ADCON1 = %11001110 ' port 0 analog, all others digital

'PortB
GMData var portb.0 'bidirecional data to/from Master Controller
GMStrobe1 var portb.1 'signals MC that GM needs attention
GMStrobe2 var portb.2 'signals GM that MC has data
GMSpare var portb.3 'a PCB trace between PeeWee50 pin 9 and 877p36
LED2 var portb.4 'front panel LED2
N2 var portb.5 'Nitrogen solenoid
SClk var portb.6 'Intersema SClk OUT to MS5534 & 5535
DIn var portb.7 'Intersems Data In OUT from 877a to MS5534 & 5535
TRISB = %00001111
PortB = %00000000

'PortC
CO2 var portc.0 'CO2 solenoid
O2 var portc.1 'O2 solenoid
MClk var portc.2 'MClk to Intersema PWM2 32678 Hz OUT to MS5534/5
Vent var portc.3 'Vent/dump solenoid
Delvry var portc.4 'delivery solenoid controls final delivery
SpareSol var portc.5 'spare solenoid OUT
TxD var portc.6 'Boot loader and RS232 OUT
RxD var portc.7 'Boot & RS232 IN
TRISC = %10000000
PortC = %00000000

'PortD
DB4 var portd.0 'Data bit 4 to LCD
DB5 var portd.1 'Data bit 5 to LCD
DB6 var portd.2 'Data bit 6 to LCD
DB7 var portd.3 'Data bit 7 to LCD
LCDEnable var portd.4 'LCD ENABLE line OUT to LCD
RegSel var portd.5 'LCD Register Select OUT to LCD
ReadWrite var portd.6 'LCD Read/Write line OUT to LCD
LED1 var portd.7 'Front Panel LED1
TRISD = %00000000
'PortD = %00110000
PortD = %00000000

'PortE
ClrEntry var porte.0 'SWp5 to 877p8 Clears entry on front panel??? IN
Dout1 var porte.1 'Input from 14 bar Intersema
Dout2 var porte.2 'Input from 1 bar Intersema
TRISE = %11111111
PortE = %00000000

'******************* Variable assignments *********************
'OPTION_REG = %10001111 ' no pullups, prescaler to WDT /128

A var byte ' General purpose Variable
B var byte ' General purpose Variable
C var byte ' General purpose Variable
I var byte
J var byte
K var byte
FuncSel var byte ' Switch position after decoding ADC value
ADCval var word
LoopCtr var byte
U var word
V var word
W var word
X var word
Y var word
Z var word
RunFlag var bit
C1 var word ' Pressure sensitivity
C2 var word ' Pressure Offset
C3 var word ' Temp Coef of pressure sensitivity
C4 var word ' Temp Coef of Pressure Offset
C5 var word ' Reference temperature
C6 var word ' Temp coef of Temp reading
D1 var word ' raw word from 5535
D2 var word ' raw word from 5535
W1 var word ' coefficient from 5535
W2 var word ' coefficient from 5535
W3 var word ' coefficient from 5535
W4 var word ' coefficient from 5535
dT var word ' intermediate calc value
UT1 var word ' Calibration temperature
Temp var word ' Sensor temperature
Tempnegflag var bit ' set if temperature is below zero C
Press var word ' Pressure
Offset var word '
Sens var word '


'DDDDDD Darrel's code here DDDDDDDDDDDDDDDDDDDDDDDDDDDD
;---- Change these to match your hardware ---------------------------
' done above
;--------------------------------------------------------------------

low readwrite 'put the LCD into write mode
GOSUB LCD_INIT ' Do manual LCD Initialization

LCDOUT "Hello World!"
end
stop

;---- Manual LCD Initialization -------------------------------------
TempB VAR BYTE
BUSdata VAR BYTE

Send4Bit:
@ MOVE?CT 1, LCD_EREG,LCD_EBIT ; Enable LCD
@ MOVE?BB LCD_DREG, _TempB ; Put Data on the Bus R-M-W
@ if LCD_DBIT == 0 ; Bus starts at 0
TEMPB = (TEMPB & $F0) | BUSdata
@ else ; Bus starts at 4
TEMPB = (TEMPB & $0F) | (BUSdata << 4)
@ endif
@ MOVE?BB _TempB, LCD_DREG

PAUSEUS 25 ; Keep enabled extra long
@ MOVE?CT 0, LCD_EREG,LCD_EBIT ; Disable LCD
Pauseus 50
return
;-----------------------------------------
LCD_INIT:
@ MOVE?CT 0, LCD_RSREG,LCD_RSBIT ; Start with RS LOW
@ MOVE?CT 0, LCD_RSREG+80h,LCD_RSBIT ; RS is OUTPUT

@ MOVE?CT 0, LCD_EREG,LCD_EBIT ; Start with Enable LOW
@ MOVE?CT 0, LCD_EREG+80h,LCD_EBIT ; Enable is OUTPUT

@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT ; Data Bus is OUTPUT
@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +1
@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +2
@ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +3

PAUSE 1000
BUSdata = 3
GOSUB Send4Bit : pause 8 ; FunctionSet 4 times
GOSUB Send4Bit : pauseUS 200
GOSUB Send4Bit : pauseUS 200
GOSUB Send4Bit : pauseUS 200
BUSdata = 2 : GOSUB Send4Bit ; 4-bit mode

BUSdata = 2 : GOSUB Send4Bit ; 2-line, 5x7
BUSdata = 8 : GOSUB Send4Bit

BUSdata = 0 : GOSUB Send4Bit ; Display OFF
BUSdata = 8 : GOSUB Send4Bit

BUSdata = 0 : GOSUB Send4Bit ; Display Clear
BUSdata = 1 : GOSUB Send4Bit
PAUSE 3

BUSdata = 0 : GOSUB Send4Bit ; Entry Mode Set
BUSdata = 6 : GOSUB Send4Bit
PAUSE 3

BUSdata = 0 : GOSUB Send4Bit ; Display ON
BUSdata = $C : GOSUB Send4Bit

@ MOVE?CT 1, LCDINITFLAG ; Tell PBP LCD is already Initialized
return
;---------- END LCD_INIT --------------------------------------------

end