OK, I now have a PIC18F2431 with acounter set up on Timer1 and a time base set up on Timer0.
The counter was pretty straight forward but i have a few questions regarding the operation of Timer0

1/. Timer Pre-Load
Timer0 is a 16 bit timer which gives an output as it rolls over from $FFFF to 0.
An 8MHZ clock speed will provide one instruction every 500ns. For a 100Hz time base (10ms period) I would need 20000 instruction cycles (20000 x 500ns = 10ms).
A free running timer wiith no pre-load would roll over every 65536th cycle so to achieve a 20000 cycle roll over I need to pre-load the timer with 65536 - 20000 = 45536.
All good - nice clean theory however, a 45536 pre-load results in ~50Hz time base!

Here is my code:

Code:
#CONFIG
    CONFIG OSC = IRCIO
    CONFIG FCMEN = ON
    CONFIG IESO = OFF
    CONFIG PWRTEN = ON
    CONFIG BOREN = ON
    CONFIG BORV = 42
    CONFIG WDTEN = OFF
    CONFIG WDPS = 512
    CONFIG WINEN = OFF
    CONFIG PWMPIN = OFF
    CONFIG LPOL = HIGH
    CONFIG HPOL = HIGH
    CONFIG T1OSCMX = OFF
    CONFIG MCLRE = ON
    CONFIG STVREN = ON
    CONFIG LVP = OFF
    CONFIG DEBUG = OFF
    CONFIG CP0 = ON
    CONFIG CP1 = ON
    CONFIG CP2 = ON
    CONFIG CP3 = ON
    CONFIG CPB = OFF
    CONFIG CPD = OFF
    CONFIG WRT0 = OFF
    CONFIG WRT1 = OFF
    CONFIG WRT2 = OFF
    CONFIG WRT3 = OFF
    CONFIG WRTC = OFF
    CONFIG WRTB = OFF
    CONFIG WRTD = OFF
    CONFIG EBTR0 = OFF
    CONFIG EBTR1 = OFF
    CONFIG EBTR2 = OFF
    CONFIG EBTR3 = OFF
    CONFIG EBTRB = OFF
#ENDCONFIG

' Set up interrupt routine
INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
ASM
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR0_INT,  _ISR,   PBP,  yes
    endm
    INT_CREATE            ; Creates the interrupt processor
ENDASM

@   INT_ENABLE  TMR0_INT  ; Enable Timer 0 Interrupts

' Define LCD registers and bits
Define	LCD_DREG	PORTB
Define	LCD_DBIT	4
Define	LCD_RSREG	PORTA
Define	LCD_RSBIT	1
Define	LCD_EREG	PORTA
Define	LCD_EBIT	2
Define	LCD_BITS	4
Define	LCD_LINES	2

' Set up Internal Oscillator @ 8MHz
DEFINE OSC 8
OSCCON = %01110010   ' Internal oscillator, 8MHz


' Set up Timer0 
T0CON = %00001000       ' Timer off
                        ' 16 bit
                        ' Internal clock
                        ' Prescaler not assigned
T0CON.7 = 1             ' Start Timer0

' Set up I/O Ports
ANSEL0 = 0              ' No analogue input, all digital
TRISA = 0               ' ALL PORTA as outputs
PORTA = 0               ' All outputs low
TRISB = 0               ' ALL PORTB as outputs
PORTB = 0               ' All outputs low
TRISC = 0               ' Set PORTC as output
PORTC = 0               ' All outputs low


Pause 100
LCDOUT $FE,1,"   Baztronics   "
Pause 100

TMR0_Reload CON 55750   ' Reload value for ~100Hz interrupt frequency at 8MHz, prescaler 1:1
TMR0_Temp VAR WORD      ' Temporary variable use for reloading the timer

LED1 VAR PortC.2

Main:
    Pause 100
    Goto Main

' This is the interrupt routine for the TMR0 interrupt.
ISR:

    T0CON.7 = 0                         ' Stop timer

    TMR0_Temp.LOWBYTE = TMR0L
    TMR0_Temp.HighByte = TMR0H          ' Get current "time"
    TMR0_Temp.LOWBYTE = TMR0L
'    TMR0_Temp.HighByte = TMR0H
    TMR0_Temp = TMR0_Temp + TMR0_Reload ' Add reload value to get correct interval

    TMR0L = TMR0_Temp.LOWBYTE
    TMR0H = TMR0_Temp.HIGHBYTE          ' Move result back to timer 
    TMR0L = TMR0_Temp.LOWBYTE
'    TMR0H = TMR0_Temp.HIGHBYTE
    
    T0CON.7 = 1                         ' Start timer
    Toggle LED1
@ INT_RETURN
I know my internal oscillator is operating at 8MHz because my LCDOUT commands work properly.
Can anyone explain why the time base is not as predicted?

2/. TMR0L and TMR0H
The datasheet states that "TMR0H is not the high byte of the timer/counter in 16bit mode, but is actually a buffered version of the high byte of Timer0" and that it "is not directly readable nor writable."
It goes on to explain that "TMR0H is updated wth the contents of the high byte of TMR0 during a read of TMR0L" The same conditions apply for write operations.
The way I understand this, I must read the TMR0L first, this transfers the buffered data to the high byte of TMR0H and THEN I can read the high byte directly.
Obviously I have mis understood the operation as this does not work.
The only way I can get the timer to provide a stable time base is to read TMR0L twice and TMR0H once OR read TMR0H twice and TMR0L once.

Would someone be able to describe how/why the low and high bytes of TMR0 should be read/written?

Cheers
Barry
VK2XBP