gbF( 
"AN Other","ss","Fri, 22 Aug 2003 01:35:15 UTC+0100","212.56.108.219 ",
"20:27  24 aug 2004",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
// sort Key for sort on dates<BR>\
var date = new Date( userfield1 )<BR>\
if ( isNaN( date ) ) {<BR>\
    if ( isNaN( userfield1 ) ) {<BR>\
	date = new Date( \"1 aug 3000\")<BR>\
	this.date = date<BR>\
        this.sortKey = date.valueOf()<BR>\
    } else {<BR>\
       // It\'s a valid Number<BR>\
       this.sortKey = userfield1*1.0	<BR>\
    }<BR>\
} else {<BR>\
    // It\'s a valid date<BR>\
    this.date = date<BR>\
    this.sortKey = date.valueOf()<BR>\
}<BR>\
<BR>\
"
);
gbF( 
"AN Other","ss","Fri, 22 Aug 2003 01:45:46 UTC+0100","212.56.108.219 ",
"  24 aug 2004 20:45",
"userfield2",
"userfield3",
"userfield4",
"// updated Function used by sort.<BR>\
function sortCallbackFn( a, b ) {<BR>\
<BR>\
if ( ( a.sortKey - b.sortKey ) != 0 ) {<BR>\
return ( a.sortKey - b.sortKey )<BR>\
}<BR>\
<BR>\
if ( a.userfield1 != b.userfield1 ) {<BR>\
if ( a.userfield1 > b.userfield1 ){ return 1 }<BR>\
if ( a.userfield1 < b.userfield1 ){ return -1 }<BR>\
return 1<BR>\
}<BR>\
<BR>\
return ( b.count*1.0 - a.count*1.0 )<BR>\
}<BR>\
<BR>\
"
);


gbF( 
"dhr","","Wed, 29 Oct 2003 21:57:42 UTC+0100","212.56.108.219 ",
"PIC Code",
"Key scan",
"",
"",
";--------------------------------------------------------------------------<BR>\
; Sec 4.1	Button Poll Routine<BR>\
;--------------------------------------------------------------------------<BR>\
	<BR>\
IPtimeslice<BR>\
;	--_____	button press<BR>\
;	----___	<BR>\
<BR>\
;	__-----  /IPnew<BR>\
;	----___  IPlast<BR>\
;	__--___  <BR>\
; This reads all Port B inputs and looks for Press<BR>\
  MOVFW	IPnew<BR>\
  MOVWF	IPlast<BR>\
  MOVFW	PORTB<BR>\
  MOVWF	IPnew<BR>\
  ; IP last contains new setting, IPlast contains previous<BR>\
  ; look for falling edges<BR>\
  COMF	IPnew,W<BR>\
  ANDWF	IPlast,W<BR>\
  ; now force IPbuttonEvent bits to high for new pressed button<BR>\
  ; the service routine should reset the bit to clear the event.<BR>\
  IORWF	IPbuttonEvent,F<BR>\
  RETURN"
);

gbF( 
"d","email","Thu, 30 Oct 2003 09:17:44 UTC+0100","193.113.37.9 132.146.89.88",
"Extra Code for Collated data",
"userfield2",
"userfield3",
"userfield4",
"  var indexA = new Array()<BR>\
  count=0<BR>\
  for( I in gbA ){<BR>\
    indexA[ count ] = I<BR>\
    count 	    = count + 1	<BR>\
  }<BR>\
  indexA.sort()<BR>\
<BR>\
//  for( I in gbA ){<BR>\
  for( var cnt=0; cnt < indexA.length; cnt++ ){<BR>\
 <BR>\
//    var r = gbA[I]<BR>\
    var r = gbA[ indexA[cnt] ]<BR>\
"
);

gbF( 
"doug","e@h","Mon, 3 Nov 2003 08:06:16 UTC+0100","212.56.108.219 ",
"PIC Code",
"16F84 or 16F628",
"",
"",
"Code to # define for either 16F84 or 16F628<BR>\
<BR>\
;#define pic16F84 1<BR>\
#define pic16F628 1<BR>\
<BR>\
ifdef pic16F84<BR>\
	INCLUDE \"p16F84.inc\"       <BR>\
<BR>\
        LIST P=16F84, R=DEC<BR>\
	__idlocs  0x0084<BR>\
	__config  _XT_OSC&_PWRTE_ON & _WDT_OFF<BR>\
	<BR>\
	cblock 	0x0c<BR>\
	endc<BR>\
endif	<BR>\
<BR>\
ifdef pic16F628<BR>\
	INCLUDE \"p16F628.inc\"       <BR>\
        LIST P=16F628, R=DEC<BR>\
	__idlocs  0x0628<BR>\
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_CLKOUT  & _MCLRE_OFF & _LVP_OFF<BR>\
	<BR>\
	cblock 0x20<BR>\
	endc<BR>\
endif<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:08:21 UTC+0100","212.56.108.219 ",
"PIC Code",
"LCD init commands",
"",
"",
"LCDstart<BR>\
<BR>\
; Minimum reset instructions for HD44100FS<BR>\
<BR>\
; System Reset,Line Select(2),Display On<BR>\
; set up for LCD commands<BR>\
<BR>\
;     wlcdCmd($33);<BR>\
;     wlcdCmd($32);<BR>\
;     wlcdCmd($28);	 { 4 bit, 2 line, 5x7 display }<BR>\
;     wlcdCmd($01);     { Clear Display }<BR>\
;     wlcdCmd($0F);     { $0F - Display On,CursorOn,Blink }<BR>\
;     wlcdCmd($C9);     { set dd address }<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:10:00 UTC+0100","212.56.108.219 ",
"PIC Code",
"LCD HD44780 commands",
"",
"",
"<BR>\
;To know wwhich nibble is being sent initilize to 8 bit then<BR>\
;go into 4 bit mode and keep track of each nibble sent<BR>\
;<BR>\
;If using 4 bit interface only use the DB4 to DB7 pins.<BR>\
;The 8 bits comands to convert to 4 bits mode do not care<BR>\
;about the 4 LSB.<BR>\
;<BR>\
;With R/W =0 and RS=0:<BR>\
;<BR>\
;0x01	;clear display 		82us @250Hz<BR>\
;0x02	;return home 		82us @250Hz<BR>\
;0x04	;EntryModeSet 		40us @250Hz<BR>\
;  0x01	; S	1 = shift<BR>\
;  0x02  ; I/D	1= increment/0=decrement<BR>\
;0x08	;Display ON/OFF		40us @250Hz<BR>\
;  0x01	; B	Blink<BR>\
;  0x02	; C	Cursor On<BR>\
;  0x04	; D	Display On<BR>\
;0x10	;Cursor and Display Shift		40us @250Hz<BR>\
;  0x04	; s/c	Shift Display/ 0=shift Cursor<BR>\
;  0x08	; r/l	Shift Right,0=shift left<BR>\
;0x20	;Function Set		40us @250Hz<BR>\
;  0x04	; F	5x10 dots /5x7dots<BR>\
;  0x08	; N	2lines	/1lines<BR>\
;  0x10	; DL	8bits interface /4 bits interface.<BR>\
;0x40	;Set CG RAM address	40us @250Hz<BR>\
;0x80	;Set DD RAM address;	40us @250Hz<BR>\
<BR>\
;With R/W =0 and RS=1:<BR>\
;write data to CG or DD <BR>\
;With R/W =1 and RS=1:<BR>\
;Read data from CG or DD <BR>\
;<BR>\
;Send the commands below to Initilize.<BR>\
;First mop up any 4 bit commands, and convert to 8 bit,<BR>\
;either from 4 bit mode or 8 bit mode.<BR>\
;Then from 8 bit node move to  4 bit mode.<BR>\
;Then issue 4 bit commands.<BR>\
<BR>\
;     wlcdCmd($33);	 8 bit mode  - could be in 4 bit  mode	<BR>\
;     wlcdCmd($32);	 8 bit mode  - could be in 4 bit  mode	<BR>\
;     wlcdCmd($28);	 4 bit mode, 2 lines 5x7 dots<BR>\
;     wlcdCmd($01);      Clear Display could take 1.6ms<BR>\
;     wlcdCmd($0F);      $0F - Display On,CursorOn,Blink <BR>\
;     wlcdCmd($C9);      set dd address <BR>\
<BR>\
;You don\'t need to read the busy line on the display.<BR>\
;<BR>\
;PORT B		Display		LCD Pin<BR>\
;DB7		DB7		14<BR>\
;DB6		DB6		13<BR>\
;DB5		DB5		12<BR>\
;DB4		DB4		11<BR>\
;DB3		E		 6<BR>\
;		R/W	gnd	 5<BR>\
;DB2		RS		 4<BR>\
;		V0	Vlcd	 3<BR>\
;		Vdd     +5  	 2<BR>\
;		Vss	0	 1<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:11:58 UTC+0100","212.56.108.219 ",
"LCD 1200",
"Commands",
"",
"",
";Epson EA-C20017AR<BR>\
;==================<BR>\
;<BR>\
;20 char by one line.<BR>\
;<BR>\
;The display appears to be based on an SED1200F controller.<BR>\
;<BR>\
;Pin Connections        when looking at display, contacts on left.<BR>\
;<BR>\
;       1       +5V     2       Gnd        |------------------|<BR>\
;       3       Vlcd    4       Clk        |                  |<BR>\
;       5       -CS     6       A0         |    DISPLAY 20x1  |<BR>\
;       7       -WR     8       -RD        |      -           |<BR>\
;       9       DB3     10      DB2        |                  |<BR>\
;       11      DB1     12      DB0        |------------------<BR>\
;<BR>\
; Display is 20 x 1<BR>\
; Suggested values for single line mode , 10 x 1 repeated 10 x 1.<BR>\
;<BR>\
; + 5V   Pin 1<BR>\
;    |  <BR>\
;   [ ]   10k ohm<BR>\
;    |  <BR>\
;Vlcd    Pin 3<BR>\
;    |<BR>\
;   [ ]   3k ohm<BR>\
;    |<BR>\
;  GND  <BR>\
;<BR>\
;<BR>\
; For proper operation run the display as two line mode.<BR>\
;<BR>\
;<BR>\
; Initialization. leaves random characters.<BR>\
;<BR>\
;       CMD, System Reset       0,0x10<BR>\
;       CMD, DISPLAY ON         0,0x0D<BR>\
;       CMD, Line Select-On     0,0x13<BR>\
;       CMD, Cursor Home        0,0x80<BR>\
;       DATA,0x20 <BR>\
<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 3.3.2	LCD command equates<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
;<BR>\
; SED 1200F config commands A0=0<BR>\
;<BR>\
LCDsetCurDirInc EQU     0x04<BR>\
LCDsetCurDirDec EQU     0x05<BR>\
LCDCurInc       EQU     0x06<BR>\
LCDCurDec       EQU     0x07<BR>\
LCDCurBlock     EQU     0x09<BR>\
LCDCurUL	EQU     0x08<BR>\
LCDCurConst     EQU     0x0A<BR>\
LCDCurBlink     EQU     0x0B<BR>\
LCDCurDispOff   EQU     0x0C<BR>\
LCDCurDispOn    EQU     0x0D<BR>\
LCDCurOff       EQU     0x0E<BR>\
LCDCurOn	EQU     0x0F<BR>\
LCDSysReset     EQU     0x10<BR>\
LCD1line	EQU     0x12<BR>\
LCD2line	EQU     0x13<BR>\
LCDCurX0Y0      EQU     0x80	; display has two halfs of 10 chars each<BR>\
LCDCurX1Y0      EQU     0xC0	;<BR>\
LCDCurLeft0     EQU     0x80	; display 80,..,89,C0..C9<BR>\
LCDCurRight0    EQU     0xC0	;<BR>\
<BR>\
LCDCgRamAddr    EQU     0x20<BR>\
LCDCgRamData    EQU     0x40<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:14:18 UTC+0100","212.56.108.219 ",
"LCD 1200",
"Waveforms",
"",
"",
"; assume that the A0 line is correctly set,<BR>\
; Byte to be displayed is in W<BR>\
;<BR>\
; CS    ----________------------------------------------------<BR>\
; WR,CLK-----__--__------_-_-_-_--_-_-_-_--_-_-_-_--_-_-_-_---<BR>\
; DB,A0 ---x====x====x----------------------------------------<BR>\
<BR>\
<BR>\
; Assumes:- <BR>\
; LCD_DB0..3 connected to PORTB:4..7<BR>\
; RD connected to +5<BR>\
; WR,CS,A0,CLK are equated, but connected to PORTB<BR>\
; on exit PORTB<4:7> are left as inputs, so that they can<BR>\
; be used for the keyboard/buttons.<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:16:32 UTC+0100","212.56.108.219 ",
"LCD 1200",
"Waveforms",
"",
"",
"LCDwrtByte<BR>\
; assume that the A0 line is correctly set,<BR>\
; Byte to be displayed is in W<BR>\
; SED1200 LCD chip<BR>\
; CS    ----________------------------------------------------<BR>\
; WR,CLK-----__--__------_-_-_-_--_-_-_-_--_-_-_-_--_-_-_-_---<BR>\
; DB,A0 ---x====x====x----------------------------------------<BR>\
<BR>\
; HD44780 LCD chip<BR>\
;R/W	==X====================x====<BR>\
;RS	____________________________	0 for CMD, 1 for DATA<BR>\
;E	____/----\\____/-----\\_______<BR>\
;DB	==X=========X==========X====<BR>\
;	      MSN	LSN<BR>\
<BR>\
"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:22:26 UTC+0100","212.56.108.219 ",
"PIC Code",
"Serial IN 9600 baud",
"",
"",
"RS232in<BR>\
		; spin for a start bit <BR>\
;		CLRWDT<BR>\
;		BTFSS	PORTB,RS232rx	<BR>\
;		GOTO	RS232in		<BR>\
<BR>\
		CALL 	Delay6 ; 1/2 bit delay for Start bit - check with MPLAB<BR>\
		CALL    Delay5 ; bit delay<BR>\
		movlw	8<BR>\
		movwf	RSloopCnt<BR>\
RS232inL0<BR>\
		MOVFW	PORTB<BR>\
		ANDLW	 1<< RS232rx	; mask off bit<BR>\
		ADDLW	-1<< RS232rx	; use ripple carry to move into C<BR>\
		RRF		RSdata,F<BR>\
		CALL	Delay5<BR>\
		DECFSZ	RSloopCnt,f<BR>\
		goto	RS232inL0<BR>\
		COMF	RSdata,f<BR>\
		MOVFW	RSdata		<BR>\
		ADDLW	-0x0D<BR>\
		SKPNZ<BR>\
		GOTO	RSfoundCR<BR>\
		ADDLW	0x0D<BR>\
		CALL 	LCDwrtChar	<BR>\
		RETURN<BR>\
RSfoundCR<BR>\
		MOVLW	LCDCurLeftLower<BR>\
		CALL 	LCDwrtCmd	<BR>\
		RETURN<BR>\
Delay5		<BR>\
		MOVLW	0x1E<BR>\
		MOVWF	RSdell<BR>\
Delay51		DECFSZ	RSdell		; 1<BR>\
		GOTO	Delay51		; 2 clk<BR>\
		CLRWDT<BR>\
		RETURN<BR>\
;Delay 0x0F * 3 ticks of 4Mhz ~= 45us<BR>\
Delay6		<BR>\
;		RETURN<BR>\
;		MOVLW	0x0F<BR>\
		MOVLW	0x08; shorten delay as edge detector takes about 22 us<BR>\
		MOVWF	RSdell<BR>\
Delay61		DECFSZ	RSdell<BR>\
		GOTO	Delay61<BR>\
		CLRWDT<BR>\
		RETURN"
);
gbF( 
"doug","ss","Mon, 3 Nov 2003 08:28:32 UTC+0100","212.56.108.219 ",
"PIC Code",
"Macro to test Table jumps",
"",
"",
"macro to protect Jump table from stradling page boundary.<BR>\
Errors if table straddles page boundary.<BR>\
<BR>\
TEST_STRADDLE	MACRO	START<BR>\
	if high( $ ) != high( START ) <BR>\
	    Error \"Table straddles Page Boundary \" + Start<BR>\
	endif<BR>\
	endm<BR>\
<BR>\
usage:<BR>\
LCDgetByte<BR>\
... jump table code ...<BR>\
	TEST_STRADDLE	LCDgetByte"
);
gbF( 
"doug","s@s","Wed, 5 Nov 2003 08:23:38 UTC+0100","212.56.108.219 ",
"Perl Code",
"Perl code to force errors to browser",
"",
"",
"# If you are getting Interal server error messages,<BR>\
# use the code below to pipe  script errors to the browser<BR>\
use CGI::Carp ( fatalsToBrowser);<BR>\
<BR>\
# Alternatively code like:<BR>\
# uncomment line below to view compiler errors <BR>\
#<BR>\
#BEGIN { <BR>\
#$| = 1; <BR>\
#open (STDERR, \">&STDOUT\"); <BR>\
#print \"Content-type: text/html\\n\\n<pre>\\n\"; <BR>\
#} <BR>\
<BR>\
"
);

gbF( 
"name","","Sat, 17 Jan 2004 21:41:53 UTC+0100","212.56.108.219 ",
"PIC Code",
"Frequency Counter code for 12F675",
"",
"",
";--------------------------------------------------------------------------<BR>\
; Sec 4.11	Frequency Counter Code<BR>\
;-------------------------------------------------------------------------<BR>\
	cblock<BR>\
		current<BR>\
		lasttmr0<BR>\
		;BCDip0,BCDip1,BCDip2,BCDip3<BR>\
		tc0,tc1,tc2,tc3,tc4<BR>\
	endc<BR>\
<BR>\
	<BR>\
incCnt	<BR>\
	; get current count<BR>\
	movfw	current<BR>\
	movwf	lasttmr0<BR>\
	movfw	TMR0<BR>\
	movwf	current<BR>\
	subwf	lasttmr0,w<BR>\
	; we don\'t need to worry about the carry.<BR>\
	sublw	0<BR>\
	addwf	BCDip0,f		; t<BR>\
	skpc			; t+0 <BR>\
	retlw	-.24		; t+1   these values are used to adjust the main timing loop.<BR>\
	incfsz	BCDip1,f		; t+2<BR>\
	retlw	-.26		; t+3<BR>\
	incfsz	BCDip2,f		; t+4<BR>\
	retlw	-.28		; t+5<BR>\
	incfsz	BCDip3,f		; t+6<BR>\
	retlw	-.30		; t+7<BR>\
<BR>\
<BR>\
FRfreqMeter1<BR>\
	; we arm to display first of all<BR>\
	NOP<BR>\
	return<BR>\
<BR>\
FRfreqMeter<BR>\
	; turn off A to D converter<BR>\
	banksel  ADCON0<BR>\
	movlw	B\'0000000\'	;Fosc/8, A/D enabled<BR>\
	movwf	ADCON0<BR>\
<BR>\
<BR>\
	; Make sure that the pin is not used by the A to D <BR>\
	; Make sure that the Comparator inpuit is Analogue, but the output is digital<BR>\
	banksel  ANSEL<BR>\
	movlw	B\'00010010\'	;Fosc/8, A/D enabled<BR>\
	movwf	ANSEL<BR>\
<BR>\
	; make the comparator output and output <BR>\
	banksel  TRISIO<BR>\
	movlw	B\'11111011\'	;Fosc/8, A/D enabled<BR>\
	movwf	TRISIO<BR>\
<BR>\
	; Set up the comparator and Vref for the freq input<BR>\
	banksel  VRCON<BR>\
	movlw	1 << VREN | 1<<VRR | 2	; level = Vdd * 4 / 24 = 0.833 Volts if Vdd is 5 volts.<BR>\
	movwf	VRCON<BR>\
<BR>\
	; Configure the Comparator to Use Vref and GPIO pin 1<BR>\
	banksel  CMCON<BR>\
	movlw	B\'00000011\'	;<BR>\
	movwf	CMCON<BR>\
<BR>\
	; Change Prescaler and connect TMR0 ip to external<BR>\
	CLRWDT<BR>\
	; Configure Tmr 0<BR>\
	BSF	STATUS,RP0<BR>\
	; set TMR0 to increment off internal input for test purposes - CLK off internal Clock<BR>\
	MOVLW	0x0 + 0x00  + 0 	; T0CS + For Tmr0 0=/2, 1=/4, 2=/8,3=/16<BR>\
<BR>\
	; Set up CLK off external input with prescale set to 1/2.<BR>\
	MOVLW	0x0 + 0x20  + 0 	; T0CS + For Tmr0 0=/2, 1=/4, 2=/8,3=/16<BR>\
<BR>\
<BR>\
	MOVWF	OPTION_REG<BR>\
	BCF	STATUS,RP0<BR>\
	; clear Pin Change interrupt<BR>\
;	MOVFW	PORTB<BR>\
;	BCF	INTCON, RBIF<BR>\
<BR>\
	clrf	BCDip0<BR>\
	clrf	BCDip1<BR>\
	clrf	BCDip2<BR>\
	clrf	BCDip3<BR>\
<BR>\
<BR>\
    ; start measuring frquency HERE as we sample the count<BR>\
    ; adding instructions here affects the readings<BR>\
	movfw	TMR0<BR>\
	movwf	current<BR>\
<BR>\
    nop<BR>\
<BR>\
	; 2,000,000 = 1E8480<BR>\
	; using prescale of div 2<BR>\
	; These seem to work, <BR>\
	; but still underead a litte bit<BR>\
	movlw	0x81<BR>\
	movwf	tc0<BR>\
	movlw	0x85<BR>\
	movwf	tc1<BR>\
	movlw	0x1F<BR>\
	movwf	tc2<BR>\
<BR>\
freqMeter0<BR>\
;	BSF	PORTA,0	<BR>\
	nop<BR>\
	;	21 cycles<BR>\
	call	incCnt<BR>\
<BR>\
;	BCF	PORTA,0<BR>\
	nop<BR>\
<BR>\
FreqDelay<BR>\
	; w contains a fiddle factor to adjust this delay<BR>\
	; get current count<BR>\
	<BR>\
	; we don\'t need to worry about the carry.<BR>\
	addwf	tc0,f		;t<BR>\
				;t= 0<BR>\
	skpnc<BR>\
	goto	fd1		;t+1 these values are used to adjust the main timing loop.<BR>\
				;<BR>\
	decfsz	tc1,f		;t+2<BR>\
	goto	fd2		;t+3<BR>\
	decfsz	tc2,f		;t+4<BR>\
	goto	fd3		;t+5<BR>\
	goto 	fd4<BR>\
<BR>\
<BR>\
	<BR>\
fd1	<BR>\
	; replace NOP instructions with a test to see if buttons have been pressed<BR>\
	; note that theses also take 2 clock cycles<BR>\
;	btfsc	INTCON,RBIF	;t+3<BR>\
;	goto	fdEscape	;t+4<BR>\
<BR>\
	nop			;t+5<BR>\
	nop			;t+6<BR>\
f<BR>\
fd2<BR>\
;	btfsc	INTCON,RBIF	;t+5<BR>\
;	goto	fdEscape	;t+6<BR>\
	nop			;t+5<BR>\
	nop			;t+6<BR>\
fd3	goto	freqMeter0	;t+7<BR>\
fd4	goto	FRdisplayResult<BR>\
	; we have a reading so arm to display it.<BR>\
;	BCF	DoTimeSlice,DTsMeasFreq<BR>\
;	BSF	DoTimeSlice,DTsDispFreq<BR>\
<BR>\
fdEscape ; come here if escaped out offrequency measurement.<BR>\
	; The half measured frequency should not be displayed.<BR>\
<BR>\
<BR>\
	; Change Prescaler back to TMR0 clocked by Internal.<BR>\
	CLRWDT<BR>\
	; Configure Tmr 0<BR>\
	BSF	STATUS,RP0<BR>\
	; Set up prescaller for 8192 / 16 = 512 ticks perseconds.<BR>\
	MOVLW	0x0 + 2 	; For Tmr0 0=/2, 1=/4, 2=/8,3=/16<BR>\
	MOVWF	OPTION_REG<BR>\
	BCF	STATUS,RP0<BR>\
	; Set up prescaller for 8192 / 16 = 512 ticks perseconds.<BR>\
;	MOVLW	4<BR>\
;	MOVWF	CLtmr4sec<BR>\
;	return<BR>\
<BR>\
	; now run into the convert and display routine<BR>\
	; display current count<BR>\
<BR>\
<BR>\
FRdisplayResult1<BR>\
	; we arm to display first of all<BR>\
	clrf	BCDip0<BR>\
	clrf	BCDip1<BR>\
	clrf	BCDip2<BR>\
	clrf	BCDip3<BR>\
<BR>\
FRdisplayResult<BR>\
<BR>\
<BR>\
#DEFINE	buildbcdBinDec24<BR>\
;	BCF	PORTA,0<BR>\
<BR>\
;	call	bcdBinDec24<BR>\
	call    B2_BCD          ; After conversion the Decimal Number"
);
gbF( 
"name","","Sat, 17 Jan 2004 21:47:12 UTC+0100","212.56.108.219 ",
"PIC Code",
"Frequency Counter code for  12F675",
"",
"",
"The code for the frequency counter uses TMR0.<BR>\
<BR>\
TMR0 is set to divide by 2.<BR>\
<BR>\
It is periodically reads TMR0 for 2 seconds, and accumulates the difference in counts from the last sample of TMR0.<BR>\
<BR>\
In this way the count is the number of cycles of the input.<BR>\
<BR>\
The 12F675 has a comparator that can be used to make the counter more sensitive.<BR>\
<BR>\
Some of this code wasin my Logi pic."
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)
gbF( 
"doug","","Mon, 5 Apr 2004 07:54:44 UTC+0100","212.56.108.219 ",
"Serial Buffer code",
"",
"",
"",
"; take serial input <CR><LF>RHHMMC and put into buffer <BR>\
; if last char C is \'s\' then write to EEPROM<BR>\
 cblock<BR>\
   SRipBuffCnt ; input buffer counter<BR>\
   ; start of buffer<BR>\
   SRreg		; Serial Port Input routines<BR>\
   SRHh		;<BR>\
   SRhH		;<BR>\
   SRMm		;<BR>\
   SRmM		;<BR>\
   SRcmd<BR>\
   ; end of buffer<BR>\
   ;<BR>\
ENDC<BR>\
<BR>\
<BR>\
SRipbuffStart	EQU SRreg <BR>\
SRipbuffEnd	EQU SRcmd<BR>\
<BR>\
<BR>\
SRbuffInput<BR>\
		MOVWF	SRin<BR>\
		; look for line feed and reset buff cnt<BR>\
		ADDLW	-0x0A<BR>\
		BNZ		SRbuffInput1<BR>\
		MOVLW	SRipbuffStart<BR>\
		MOVWF	SRipBuffCnt<BR>\
		RETURN<BR>\
<BR>\
SRbuffInput1		<BR>\
		; Store the current time into the next register.<BR>\
		MOVFW	SRipBuffCnt<BR>\
		MOVWF	FSR<BR>\
		MOVFW	SRin<BR>\
		MOVWF	INDF<BR>\
		INCFSZ	SRipBuffCnt,f<BR>\
		MOVFW	SRipBuffCnt<BR>\
<BR>\
		ADDLW	-(SRipbuffEnd+1)<BR>\
		; Check if the end of memory<BR>\
		SKPZ	<BR>\
		GOTO	SRbuffInput3	<BR>\
		MOVLW	SRipbuffStart<BR>\
		MOVWF	SRipBuffCnt<BR>\
<BR>\
		; got to end of buffer so process. does not allow for backspace<BR>\
		MOVLW	-\'s\'<BR>\
	    ADDWF	SRcmd,w	; test to see if command is s, if so save into register.<BR>\
		bnz 	SRbuffInput3		<BR>\
<BR>\
		; assume numbers were typed<BR>\
		; mask off lower nibble<BR>\
		MOVLW	0x0F<BR>\
		ANDWF	SRreg,f<BR>\
		ANDWF	SRHh,f<BR>\
		ANDWF	SRhH,f<BR>\
		ANDWF	SRMm,f<BR>\
		ANDWF	SRmM,f<BR>\
<BR>\
		RLF		SRreg,w<BR>\
		ANDLW	0x1E<BR>\
		MOVWF	EEADR<BR>\
		SWAPF	SRHh,w<BR>\
		IORWF	SRhH,w<BR>\
		CALL	EEwrt<BR>\
<BR>\
		RLF		SRreg,w<BR>\
		ANDLW	0x1E<BR>\
		ADDLW	0x01<BR>\
		MOVWF	EEADR<BR>\
		SWAPF	SRMm,w<BR>\
		IORWF	SRmM,w<BR>\
		CALL	EEwrt<BR>\
<BR>\
		GOTO	SRbuffInput3<BR>\
SRbuffInput3<BR>\
<BR>\
<BR>\
	    return<BR>\
<BR>\
"
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)
gbF( 
"Doug ","","Fri, 31 Dec 2004 07:45:57 UTC+0100","212.56.108.219 ",
"Input - edge detector",
"",
"",
"",
"<BR>\
IPtimeslice<BR>\
		;	----___<BR>\
		;	--_____<BR>\
		;<BR>\
		; This reads all Port B inputs and looks for Press<BR>\
		MOVFW	IPnew<BR>\
		MOVWF	IPlast<BR>\
		MOVFW	PORT_BUTTONS<BR>\
		MOVWF	IPnew<BR>\
		<BR>\
		; IP last contains new setting, IPlast contains previous<BR>\
<BR>\
		;	----___<BR>\
		;	--_____<BR>\
		;<BR>\
<BR>\
		; trigger event on down and up <BR>\
		MOVFW	IPnew	; ----______<BR>\
		XORWF	IPlast,W	; -----_____ <BR>\
						; ____-_____<BR>\
		; now force IPbuttonEvent bits to high for new pressed button<BR>\
		; the service routine should clear the bit to clear the event.<BR>\
		IORWF	IPbuttonEventt,F<BR>\
		; RETURN<BR>\
<BR>\
		; trigger event on press		<BR>\
		COMF	IPnew,W	; ____------<BR>\
		ANDWF	IPlast,W	; -----_____ <BR>\
						; ____-_____<BR>\
		; now force IPbuttonEvent bits to high for new pressed button<BR>\
		; the service routine should clear the bit to clear the event.<BR>\
		IORWF	IPbuttonEvent,F<BR>\
		RETURN<BR>\
"
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)
gbF( 
"name","","Fri, 31 Dec 2004 07:48:33 UTC+0100","212.56.108.219 ",
"Input - ",
"",
"",
"",
"MainLoop	<BR>\
		CALL	IPtimeslice<BR>\
		CALL	CLtimeslice<BR>\
<BR>\
<BR>\
		; Any events that exist<BR>\
		BTFSC	DoTimeSlice,DTsS4event	; On 1/4 Second Tick<BR>\
		CALL	SS4tick<BR>\
<BR>\
		; Any events that exist<BR>\
		BTFSC	DoTimeSlice,DTsSevent	; On Second Tick<BR>\
		CALL	SStick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTsMevent	; On Minute Tick<BR>\
		CALL	SMtick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTsHevent	; On Hour Tick<BR>\
		CALL	SHtick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTSRwrtCount	; Serial Display<BR>\
		CALL	SRwrtCount<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTSRwrtEvent	; Serial Display<BR>\
		CALL	SRwrtTime<BR>\
<BR>\
#ifdef inc<BR>\
<BR>\
		BTFSC	IPbuttonEvent,BUTTON_SET	; On BUTTON_SET Press<BR>\
		CALL	IPsetPressed<BR>\
<BR>\
		BTFSC	IPbuttonEvent,BUTTON_NEXT	; On BUTTON_NEXT Press<BR>\
		CALL	IPnextPressed<BR>\
<BR>\
#endif<BR>\
		BTFSC	IPbuttonEventt,BUTTON_ONE	; On BUTTON_NEXT Press<BR>\
		CALL	IPoneChanged<BR>\
<BR>\
<BR>\
		; CALL	IPtimesliceFast ; also does switch action if edge found.<BR>\
; 		this is normally called eververy 1/4 second		<BR>\
;		CALL	IPts<BR>\
<BR>\
		GOTO 	MainLoop<BR>\
"
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)
gbF( 
"name","","Fri, 31 Dec 2004 07:49:09 UTC+0100","212.56.108.219 ",
"Input - Main loop",
"",
"",
"",
"name said on Fri, 31 Dec 2004 07:48:33 UTC+0100:<BR>\
MainLoop	<BR>\
		CALL	IPtimeslice<BR>\
		CALL	CLtimeslice<BR>\
<BR>\
<BR>\
		; Any events that exist<BR>\
		BTFSC	DoTimeSlice,DTsS4event	; On 1/4 Second Tick<BR>\
		CALL	SS4tick<BR>\
<BR>\
		; Any events that exist<BR>\
		BTFSC	DoTimeSlice,DTsSevent	; On Second Tick<BR>\
		CALL	SStick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTsMevent	; On Minute Tick<BR>\
		CALL	SMtick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTsHevent	; On Hour Tick<BR>\
		CALL	SHtick<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTSRwrtCount	; Serial Display<BR>\
		CALL	SRwrtCount<BR>\
<BR>\
		BTFSC	DoTimeSlice,DTSRwrtEvent	; Serial Display<BR>\
		CALL	SRwrtTime<BR>\
<BR>\
#ifdef inc<BR>\
<BR>\
		BTFSC	IPbuttonEvent,BUTTON_SET	; On BUTTON_SET Press<BR>\
		CALL	IPsetPressed<BR>\
<BR>\
		BTFSC	IPbuttonEvent,BUTTON_NEXT	; On BUTTON_NEXT Press<BR>\
		CALL	IPnextPressed<BR>\
<BR>\
#endif<BR>\
		BTFSC	IPbuttonEventt,BUTTON_ONE	; On BUTTON_NEXT Press<BR>\
		CALL	IPoneChanged<BR>\
<BR>\
<BR>\
		; CALL	IPtimesliceFast ; also does switch action if edge found.<BR>\
; 		this is normally called eververy 1/4 second		<BR>\
;		CALL	IPts<BR>\
<BR>\
		GOTO 	MainLoop<BR>\
"
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)
gbF( 
"name","","Fri, 31 Dec 2004 07:50:53 UTC+0100","212.56.108.219 ",
"Input - One button timmed press",
"",
"",
"",
"<BR>\
IPoneChanged	<BR>\
		BCF		IPbuttonEventt,BUTTON_ONE<BR>\
		; test for up/down<BR>\
		BTFSC	IPnew,BUTTON_ONE<BR>\
		GOTO	IPoneReleased<BR>\
IPonePressed	<BR>\
		CALL	LSblink<BR>\
		MOVLW	B\'10001000\'	; load a set of pegs, like one a music box into byte.<BR>\
		MOVWF 	IPoneTimer	; this timer uses a shitf reg<BR>\
		MOVLW	0<BR>\
		MOVWF	IPoneCnt<BR>\
		RETURN<BR>\
		<BR>\
IPoneReleased<BR>\
		CLRF	IPoneTimer	; clear the timer<BR>\
		<BR>\
		MOVFW	IPoneCnt<BR>\
		ADDLW	-2			; jump if 2 or 3		<BR>\
		BC		IPoneReleased2<BR>\
			<BR>\
		MOVFW	IPoneCnt		; 0 = next, 1 = set<BR>\
		CALL 	IPsetJump<BR>\
		<BR>\
		MOVWF	IPsetState<BR>\
		SWAPF	IPsetState,W<BR>\
		MOVWF	PORTA<BR>\
		RETURN<BR>\
		<BR>\
IPoneReleased2<BR>\
		CLRF	DispState<BR>\
		CLRF	IPsetState<BR>\
			<BR>\
		SWAPF	IPsetState,W<BR>\
		MOVWF	PORTA	<BR>\
		RETURN<BR>\
<BR>\
IPts<BR>\
		; This is called once per 1/4 second<BR>\
		BCF		STATUS,C<BR>\
		RRF		IPoneTimer,f	; shift the timer pegs to right. If peg moves into carry do something.<BR>\
		BTFSS	STATUS,C		; Thest if a peg is set 	<BR>\
		RETURN<BR>\
		; blink LED<BR>\
		INCF	IPoneCnt,f<BR>\
		; multiply the IPcnt by 16 by doing a swap.		<BR>\
		SWAPF	IPoneCnt,w	<BR>\
		MOVlw	0x08<BR>\
		CALL	LSbeepn<BR>\
		return"
);
//HTTP_REFERER   = http://www.dougrice.plus.com/hp/gbbook/simple/codeScraps.htm
//HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)
gbF( 
"name","","Fri, 31 Dec 2004 07:55:04 UTC+0100","212.56.108.219 ",
"Input - One button timmed press.",
"",
"First Try",
"",
"#ifdef works<BR>\
<BR>\
IPoneChanged	<BR>\
		BCF		IPbuttonEventt,BUTTON_ONE<BR>\
		; test for up/down<BR>\
		BTFSC	IPnew,BUTTON_ONE<BR>\
		GOTO	IPoneReleased<BR>\
IPonePressed	<BR>\
		MOVLW	B\'10010010\'	; load a set of pegs, like one a music box into byte.<BR>\
		MOVWF 	IPoneTimer	; this timer uses a shitf reg<BR>\
		MOVLW	1<BR>\
		MOVWF	IPoneCnt<BR>\
		RETURN<BR>\
IPoneReleased<BR>\
		CLRF	IPoneTimer	; clear the timer<BR>\
		SWAPF	IPoneCnt,w<BR>\
		CALL	LSbeepn<BR>\
		DECF	IPoneCnt,W<BR>\
		MOVWF	PORTA<BR>\
		RETURN<BR>\
<BR>\
IPts<BR>\
		; This is called once per 1/4 second<BR>\
		BCF		STATUS,C<BR>\
		RRF		IPoneTimer,f	; shift the timer pegs to right. If peg moves into carry do something.<BR>\
		BTFSS	STATUS,C		; Thest if a peg is set 	<BR>\
		RETURN<BR>\
		; blink LED<BR>\
		INCF	IPoneCnt,f<BR>\
		; multiply the IPcnt by 16 by doing a swap.		<BR>\
		SWAPF	IPoneCnt,w	<BR>\
		MOVlw	0x08<BR>\
		CALL	LSbeepn<BR>\
		return<BR>\
#endif<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Wed, 19 Jul 2006 08:07:24 UTC+0100","212.56.108.219 ",
"; Binary-to-BCD.  Written by John Payson.",
"userfield2",
"userfield3",
"userfield4",
";-------------------------------------------------------------------<BR>\
; http://www.interstice.com/~sdattalo/technical/software/pic/bcd.txt<BR>\
;<BR>\
; Binary-to-BCD.  Written by John Payson.<BR>\
;<BR>\
; Enter with 16-bit binary number in NumH:NumL.<BR>\
; Exits with BCD equivalent in TenK:Thou:Hund:Tens:Ones.<BR>\
;<BR>\
<BR>\
;        org     0x0010   ;Start of user files for 16c84<BR>\
;	cblock<BR>\
;		NumH;:   ds      1<BR>\
;		NumL;:   ds      1<BR>\
;		TenK;:   ds      1<BR>\
;		Thou;:   ds      1<BR>\
;		Hund;:   ds      1<BR>\
;		Tens;:   ds      1<BR>\
;		Ones;:   ds      1<BR>\
;	endc<BR>\
<BR>\
Convert;:                        ; Takes number in NumH;:NumL<BR>\
                                ; Returns decimal in<BR>\
                                ; TenK;:Thou;:Hund;:Tens;:Ones<BR>\
				;Carrying this concept out for the rest of the b_i\'s we have.<BR>\
				;<BR>\
				;b_0 = a_0 - 4*(a_3 + a_2 + a_1) - 20<BR>\
				;b_1 = 6*a_2 + 2*a_1 + 2 - 140<BR>\
				;    = 6*a_2 + 2*a_1 - 138<BR>\
				;b_2 = a_3 + 2*a_2 + 14 - 60<BR>\
				;    = a_3 + 2*a_2 - 46<BR>\
				;b_3 = 4*a_3 + 6 - 70<BR>\
				;    = 4*a_3 - 64<BR>\
				;b_4 = 0 + 7<BR>\
				;    = 7<BR>\
<BR>\
<BR>\
				<BR>\
        swapf   NumH,w<BR>\
        andlw   0x0F             ;*** PERSONALLY, I\'D REPLACE THESE 2<BR>\
        addlw   0xF0             ;*** LINES WITH \"IORLW 11110000B\" -AW<BR>\
				;	=a3+240 or 	=a3-16<BR>\
        movwf   Thou		;   w = a3-16<BR>\
        addwf   Thou,f		;thou = 2a3-32<BR>\
        addlw   0xE2		;   w = a3-16-30<BR>\
        movwf   Hund		;hund = a3-46 <BR>\
        addlw   0x32		;   w = a3-46+50 = a3 + 4<BR>\
        movwf   Ones		;ones = a3 +4<BR>\
<BR>\
        movf    NumH,w		;	<BR>\
        andlw   0x0F		;   w = a2<BR>\
        addwf   Hund,f		;hund = a3-46 + a2<BR>\
        addwf   Hund,f		;hund = a3-46 + 2*a2<BR>\
        addwf   Ones,f		;Ones = a3+4  + a2<BR>\
        addlw   0xE9<BR>\
        movwf   Tens		;Tens = a2 - 23<BR>\
        addwf   Tens,f		;Tens = 2*(a2 - 23)<BR>\
        addwf   Tens,f		;Tens = 3*(a2 - 23)<BR>\
<BR>\
        swapf   NumL,w		<BR>\
        andlw   0x0F		;   w = a1<BR>\
        addwf   Tens,f		;<BR>\
        addwf   Ones,f		;<BR>\
<BR>\
        rlf     Tens,f<BR>\
        rlf     Ones,f<BR>\
        comf    Ones,f<BR>\
        rlf     Ones,f<BR>\
<BR>\
        movf    NumL,w		;<BR>\
        andlw   0x0F		;  w = a0<BR>\
        addwf   Ones,f<BR>\
        rlf     Thou,f<BR>\
<BR>\
        movlw   0x07<BR>\
        movwf   TenK<BR>\
<BR>\
                        ; At this point, the original number is<BR>\
                        ; equal to<BR>\
                        ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones ;<BR>\
                        ; if those entities are regarded as two\'s<BR>\
                        ; compliment ; binary.  To be precise, all of<BR>\
                        ; them are negative ; except TenK.  Now the<BR>\
                        ; number needs to be normal- ; ized, but this<BR>\
                        ; can all be done with simple byte ; arithmetic.<BR>\
<BR>\
        movlw   0x0A                             ; Ten<BR>\
Lb1;:<BR>\
        addwf   Ones,f<BR>\
        decf    Tens,f<BR>\
        btfss   3,0<BR>\
         goto   Lb1<BR>\
Lb2;:<BR>\
        addwf   Tens,f<BR>\
        decf    Hund,f<BR>\
        btfss   3,0<BR>\
         goto   Lb2<BR>\
Lb3;:<BR>\
        addwf   Hund,f<BR>\
        decf    Thou,f<BR>\
        btfss   3,0<BR>\
         goto   Lb3<BR>\
Lb4;:<BR>\
        addwf   Thou,f<BR>\
        decf    TenK,f<BR>\
        btfss   3,0<BR>\
         goto   Lb4<BR>\
<BR>\
        retlw   0<BR>\
<BR>\
<BR>\
; And according to my analysis;:<BR>\
;<BR>\
; If you have a 4 digit hexadecimal number, it may be written as<BR>\
;<BR>\
; N = a_3*16^3 + a_2*16^2 + a_1*16 + a_0<BR>\
;<BR>\
; where a_i, i=0,1,2,3 are the four hexadecimal digits. If you <BR>\
; wish to convert this to decimal, then you need to express N as<BR>\
;<BR>\
; N = b_4*10^4 + b_3*10^3 + b_2*10^2 + b_1*10 + b_0<BR>\
;<BR>\
; Where b_j, j=0,1,2,3,4 are the five decimal digits.<BR>\
; The reason there are 5 digits in the decimal representation<BR>\
; is because the maximum four digit hexadecimal number (0xffff)<BR>\
; requires 5 decimal digits (65535). Now the goal is to find<BR>\
; a set of equations that allow the b_j\'s to be expressed in<BR>\
; terms of the a_i\'s. There are infinitely many ways to do this.<BR>\
; Here are two of probably the simplest expressions.<BR>\
;  First, expand the 16^i\'s and then collect all coefficients<BR>\
; of the 10^j\'s;:<BR>\
;<BR>\
; N = a_3*4096 + a_2*256 + a_1*16 + a_0<BR>\
;  = a_3*4*10^3  + a_2*2*10^2 + (a_3*9 + a_2*5 + a_1)*10 +<BR>\
;    6*(a_3 + a_2 + a_1) + a_0<BR>\
;<BR>\
;<BR>\
;This gives us five equations;:<BR>\
;<BR>\
;b_0 = 6*(a_3 + a_2 + a_1) + a_0<BR>\
;b_1 = a_3*9 + a_2*5 + a_1<BR>\
;b_2 = 2*a_2<BR>\
;b_3 = 4*a_3<BR>\
;b_4 = 0<BR>\
;<BR>\
;Which as John says, must be \"normalized\". Normalization in<BR>\
;this context means we need to reduce the b_j\'s such that<BR>\
;  0 <= b_j <= 9<BR>\
;<BR>\
;In other words we need to find;:<BR>\
;<BR>\
;c_0 = b_0 mod 10<BR>\
;<BR>\
;b_1 = (b_1 + (b_0 - c_0)/10)<BR>\
;c_1 =  b_1 mod 10<BR>\
;<BR>\
;b_2 = (b_2 + (b_1 - c_1)/10) <BR>\
;c_2 = b_2 mod 10<BR>\
;<BR>\
;b_3 = (b_3 + (b_2 - c_2)/10)<BR>\
;c_3 = b_3 mod 10<BR>\
;<BR>\
;c_4 = (b_4 + (b_3 - c_3)/10) mod 10<BR>\
;    = (b_2 - c_2)/10<BR>\
;<BR>\
;Division by 10 can be done quite efficiently (as was shown<BR>\
;in another thread several months ago). However, it does require<BR>\
;a significant amount of code space compared to say repeated<BR>\
;subtractions. Unfortunately, there can be very many subtractions<BR>\
;that are required. For example, b_1 could be as large as 15*16,<BR>\
;or 240. 10 would have to be subtracted 24 times if you wish to<BR>\
;compute 240 mod 10. I presume John realized this inefficiency<BR>\
;and thus sought to express N so that repeated subtractions<BR>\
;could be used and that the total number of subtractions are<BR>\
;minimized. This leads to the next way that N can be expressed;:<BR>\
;<BR>\
;N = a_3*(4100 - 4) + a_2*(260 - 4) + a_1*(20-4) + a_0<BR>\
;  = 4*a_3*10^3 + (a_3 + 2*a_2)*10^2 + (6*a_2 + 2*a_1)*10 +<BR>\
;    a_0 - 4*(a_3 + a_2 + a_1)<BR>\
;<BR>\
;This gives five new equations for the b_j\'s. <BR>\
;<BR>\
;b_0 = a_0 - 4*(a_3 + a_2 + a_1)<BR>\
;b_1 = 6*a_2 + 2*a_1<BR>\
;b_2 = a_3 + 2*a_2<BR>\
;b_3 = 4*a_3<BR>\
;b_4 = 0<BR>\
;<BR>\
;However, these equations are still not conducive to the <BR>\
;repeated subtraction algorithm, at least the way John has <BR>\
;done it. In other words, it is possible to pre-condition <BR>\
;each of the b_j\'s so that they are less than zero. Then <BR>\
;the repeated subtractions can simultaneously perform the<BR>\
;\"mod 10\" and \"/10\" operations shown above. Consider the<BR>\
;equation b_0 for example, <BR>\
;<BR>\
;b_0 = a_0 - 4*(a_3 + a_2 + a_1)<BR>\
;<BR>\
;Since each a_i must satisfy;:  0 <= a_i <= 15, then b_0 <BR>\
;ranges;:<BR>\
;<BR>\
; -60 <= b_0 <= 15<BR>\
;<BR>\
;We can make b_0 negative by subtracting any number greater than<BR>\
;15. A logical choice is 20. This is because if we subtract 20<BR>\
;from b_0, we can add 2 to b_1 to keep the net result the same.<BR>\
;The reason we add \"2\" can be seen;:<BR>\
;<BR>\
; b_1*10 + b_0 = b_1*10 + b_0 + 20 - 20<BR>\
;              = (b_1 + 2)*10 + b_0 - 20<BR>\
;<BR>\
;Carrying this concept out for the rest of the b_i\'s we have.<BR>\
;<BR>\
;b_0 = a_0 - 4*(a_3 + a_2 + a_1) - 20<BR>\
;b_1 = 6*a_2 + 2*a_1 + 2 - 140<BR>\
;    = 6*a_2 + 2*a_1 - 138<BR>\
;b_2 = a_3 + 2*a_2 + 14 - 60<BR>\
;    = a_3 + 2*a_2 - 46<BR>\
;b_3 = 4*a_3 + 6 - 70<BR>\
;    = 4*a_3 - 64<BR>\
;b_4 = 0 + 7<BR>\
;    = 7<BR>\
;<BR>\
;And if you look at John\'s code closely, you will see this is<BR>\
;how he has expressed the b_j\'s.<BR>\
;<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"name","","Thu, 24 Apr 2008 07:39:21 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"MQC Test Args",
"userfield2",
"userfield3",
"userfield4",
"This crap is just too hard to figure out and find. This is buried in several other threads that talk about AOM, which is of no help if all you want to know is \"how do I pass test parameters to/from QC\":<BR>\
<BR>\
foo = TestArgs(\"testParmName\") \'get an input test parameter<BR>\
<BR>\
<BR>\
This is the logical equivalent of dereferencing an Action parameter, which is the following syntax:<BR>\
<BR>\
bar= Parameter(\"actionParmName\")<BR>\
<BR>\
Most confusing as far as I am concerned, as TestArgs has no entry in online help.<BR>\
<BR>\
-Terry<BR>\
<BR>\
P.S. Additional Search phrases:<BR>\
<BR>\
dereference \"test para\" \"test arg\" <BR>\
"
);
gbF( // guestbook.pl 
"name","","Thu, 24 Apr 2008 07:47:42 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"MQC Test Args",
"userfield2",
"userfield3",
"userfield4",
"name said on Thu, 24 Apr 2008 07:39:21 UTC+0100:<BR>\
This crap is just too hard to figure out and find. This is buried in several other threads that talk about AOM, which is of no help if all you want to know is \"how do I pass test parameters to/from QC\":<BR>\
<BR>\
foo = TestArgs(\"testParmName\") \'get an input test parameter<BR>\
<BR>\
<BR>\
This is the logical equivalent of dereferencing an Action parameter, which is the following syntax:<BR>\
<BR>\
bar= Parameter(\"actionParmName\")<BR>\
<BR>\
Most confusing as far as I am concerned, as TestArgs has no entry in online help.<BR>\
<BR>\
-Terry<BR>\
<BR>\
P.S. Additional Search phrases:<BR>\
<BR>\
dereference \"test para\" \"test arg\" <BR>\
<BR>\
<BR>\
http://www.itjobswatch.co.uk/jobs/uk/winrunner.do<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Tue, 13 May 2008 08:59:10 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"Jump Table code",
"",
"",
"",
"<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 4.1 jump and look up tables.<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
; Jump table W added to PCL to jump into table<BR>\
; Call this routine and W contains value from jump table<BR>\
; W contains the address of the string to be displayed<BR>\
<BR>\
LClookUpPtr<BR>\
    movwf	LCptr<BR>\
    movlw	high LClookUpPtrTable<BR>\
    movwf	PCLATH<BR>\
    movfw	LCptr<BR>\
    addwf	PCL,f<BR>\
<BR>\
LClookUpPtrTable	<BR>\
	RETLW low LCstr1<BR>\
	RETLW low LCstr2<BR>\
	RETLW low LCstr3<BR>\
	RETLW low LCstr4<BR>\
	RETLW low LCstr0<BR>\
	TEST_STRADDLE( LCsetPtr )<BR>\
<BR>\
	; LCptr is loaded into PCL and incremented<BR>\
	; Call this routine and W contains value from jump table<BR>\
LCnextWordTableGet	<BR>\
	movlw   high LCnextWordTable<BR>\
	movwf	PCLATH<BR>\
	movfw	LCptr<BR>\
 	incf	LCptr,f<BR>\
	movwf	PCL<BR>\
<BR>\
LCnextWordTable	<BR>\
LCstr0<BR>\
	dt \"sed1300: \"<BR>\
	goto LCend<BR>\
<BR>\
LCstr1<BR>\
	dt \"- start -\"<BR>\
	goto LCend<BR>\
<BR>\
LCstr2	<BR>\
	dt \"- stop  -\"<BR>\
	goto LCend<BR>\
<BR>\
LCstr3	<BR>\
	dt \"= go =\"<BR>\
	goto LCend<BR>\
<BR>\
LCstr4	<BR>\
	dt \"= wait =\"<BR>\
	goto LClast<BR>\
		<BR>\
	TEST_STRADDLE( LCnextWordTableGet )<BR>\
<BR>\
<BR>\
<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 4.2 	Main Program Init Code<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
Start<BR>\
	GOTO 	$+1<BR>\
<BR>\
	CALL 	INinit<BR>\
	CALL	LCinit<BR>\
<BR>\
	<BR>\
	<BR>\
	MOVLW	0x01<BR>\
	XORWF	LCflags,f<BR>\
	<BR>\
	MOVLW	0xFF<BR>\
	MOVWF	LCdelayConst<BR>\
	<BR>\
	call	LClast	<BR>\
<BR>\
<BR>\
	MOVLW	2<BR>\
	CALL	LCsetPtr<BR>\
<BR>\
	CALL	LCnextWord<BR>\
	CALL	LCnextWord<BR>\
	CALL	LCnextWord<BR>\
<BR>\
	GOTO	MainLoop<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"Doug","","Sun, 18 May 2008 08:22:23 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"LUA - Bit test",
"userfield2",
"userfield3",
"userfield4",
"-- LUA does not provide a bit test function. You could code a .dll<BR>\
-- Here is a simple bit test <BR>\
-- test 0x20 <BR>\
-- test if bit 6 is set. <BR>\
-- for an ASN decompose to check for structures look for bit 6 = 1<BR>\
<BR>\
a = 0x20<BR>\
print ( a % 64 ) > 32 <BR>\
<BR>\
a = 0x0<BR>\
print ( a % 64 ) > 32 <BR>\
"
);
gbF( // guestbook.pl 
"name","","Sun, 18 May 2008 08:28:37 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"LUA - Bit masks ",
"userfield2",
"userfield3",
"userfield4",
"Doug said on Sun, 18 May 2008 08:22:23 UTC+0100:<BR>\
-- LUA does not provide a bit test function. You could code a .dll<BR>\
-- Here is a simple bit test <BR>\
-- test 0x20 <BR>\
-- test if bit 6 is set. <BR>\
-- for an ASN decompose to check for structures look for bit 6 = 1<BR>\
<BR>\
--<BR>\
a = 0xA1 <BR>\
-- 0x1010 1111<BR>\
<BR>\
> Masking off bits<BR>\
stdin:1: \'=\' expected near \'off\'<BR>\
> -- masking off bit fields.<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
32<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
32<BR>\
> a = 0xb7<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
48<BR>\
>"
);
gbF( // guestbook.pl 
"name","","Sun, 18 May 2008 08:29:24 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"LUA - Bit masks ",
"userfield2",
"userfield3",
"userfield4",
"Doug said on Sun, 18 May 2008 08:22:23 UTC+0100:<BR>\
-- LUA does not provide a bit test function. You could code a .dll<BR>\
-- Here is a simple bit test <BR>\
-- test 0x20 <BR>\
-- test if bit 6 is set. <BR>\
-- for an ASN decompose to check for structures look for bit 6 = 1<BR>\
<BR>\
--<BR>\
a = 0xA1 <BR>\
-- 0x1010 1111<BR>\
<BR>\
> Masking off bits<BR>\
stdin:1: \'=\' expected near \'off\'<BR>\
> -- masking off bit fields.<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
32<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
32<BR>\
> a = 0xb7<BR>\
> = ( a % 64 ) - ( a % 16 )<BR>\
48<BR>\
>"
);
gbF( // guestbook.pl 
"name","","Mon, 19 May 2008 08:15:13 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"LUA - Date Stame",
"userfield2",
"userfield3",
"userfield4",
"--<BR>\
--<BR>\
--==================================<BR>\
--Sun, 20 Apr 2008 08:51:06 UTC+0100<BR>\
--==================================<BR>\
--<BR>\
--<BR>\
<BR>\
opStrHdr = \"==================================\\n\" .. <BR>\
           os.date( \"!%a, %d %b %Y %X\" ) .. \" UTC\" .. \"\\n\" ..<BR>\
           \"==================================\\n\"  <BR>\
<BR>\
print( opStrHdr .. opStr )"
);
gbF( // guestbook.pl 
"doug","","Wed, 21 May 2008 07:29:55 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - ",
"userfield2",
"userfield3",
"userfield4",
"; IIC master commands to set to slave and master. <BR>\
;    Master is done by code. EEPROM<BR>\
;<BR>\
;	<CR><;	IIC START<BR>\
;	<CR>>;	IIC STOP<BR>\
;	<CR>/DD;	IIC master writeByte<BR>\
;	<CR>?;	IIC master readByte.  If you get ~, SCL is being held low and read has timed out.<BR>\
;<BR>\
;	you need to W86FF to set PORT-B & SCL and SDA to IIC inputs.<BR>\
;	you need to W9340 to set IIC ADDR<BR>\
;	you need to W1436 to init IIC<BR>\
;<BR>\
;	<c6; 	send start and Address<BR>\
;	/56; send DATA<BR>\
;	>;<BR>\
;<BR>\
;	<c7; 	send start and Address<BR>\
;	W13DD; write data<BR>\
;	W1436; set CLK enable<BR>\
;	?;   master read data.<BR>\
;	>;<BR>\
;<BR>\
;<BR>\
; start, addr+r/~w, ACK, data, ACK , data , ACK , stop<BR>\
;<BR>\
;<BR>\
; On IIC int if using SSPCON=36;<BR>\
;  if Sbit<BR>\
;	   if D/~A == A  ; address<BR>\
;		if R/~W == R ; Call readFirst - slave must write byte to be read into SSPBUF , Could reset state machine.<BR>\
;		if R/~W == W ; Call writeFirst - slave could read Address use it, It will hold SCL low while processing byte.<BR>\
;<BR>\
;	   if D/~A == D  ; data<BR>\
;		if R/~W == R ; Call readNext - slave must write byte to be read into SSPBUF<BR>\
;		if R/~W == W ; Call writeNext - slave must read byte and use, It will hold SCL low while processing byte.<BR>\
;<BR>\
;  if Pbit<BR>\
;	 ; iic bus has gone idle <BR>\
;<BR>\
;	 if ( D/~A == A ) && ( BF==1 ) ; Address received<BR>\
;	   if ( R/~W == W ) then call resetIICwrite;<BR>\
;	   if ( R/~W == R ) then call resetIICread;<BR>\
;<BR>\
;  if ( BF == 0 ) && ( R/~W == R ) ?;<BR>\
;<BR>\
; address 0x20 bit 7 controls if interupt is polled.<BR>\
;<BR>\
;<BR>\
; write<BR>\
; w9340 to set address<BR>\
; w1400 to reset <BR>\
; w1436 to set mode<BR>\
; <;<BR>\
; /40;<BR>\
; r13;<BR>\
; /45;<BR>\
; >;<BR>\
;<BR>\
; read<BR>\
; w9340 to set address<BR>\
; w1400 to reset <BR>\
; w1436 to set mode<BR>\
; <;<BR>\
; /41;<BR>\
; w1345;<BR>\
; w1436 to set CLKE<BR>\
; ?<BR>\
; w1377; respond with 77<BR>\
; w1436 to set CLKE<BR>\
; ?<BR>\
; >;<BR>\
;<BR>\
;<BR>\
; SERIAL PORT CONTROL:<BR>\
;<BR>\
;	PORT A0 is Serial input<BR>\
;	PORT A0 is serial output<BR>\
;<BR>\
;	usb gmus-03 USB Serial Adapter<BR>\
;<BR>\
;	TX  D9 Pin 3 -[4k7]----+-----PA0<BR>\
;	RX  D9 Pin 2 ----------/<BR>\
;<BR>\
;	GND D9 Pin 5 ---------------- 0V<BR>\
; <BR>\
; AUTHOR:  Douglas Rice<BR>\
; Copyright 2004<BR>\
;<BR>\
;<BR>\
;**************************************************************************<BR>\
"
);
gbF( // guestbook.pl 
"doug","email","Wed, 21 May 2008 07:30:31 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - code",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 5.6a 	IIC Routines - these do not use the chipps IIC hardware<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
<BR>\
IICinit<BR>\
	MOVLW 	0xFF<BR>\
     banksel 	TRISB<BR>\
	MOVWF  	TRISB<BR>\
	<BR>\
	MOVLW 	0x10<BR>\
     banksel 	SSPADD<BR>\
	MOVWF  	SSPADD<BR>\
	<BR>\
	MOVLW 	0x36<BR>\
     banksel 	SSPCON<BR>\
	MOVWF  	SSPCON<BR>\
	<BR>\
	return<BR>\
<BR>\
<BR>\
<BR>\
	<BR>\
	<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 5.6b 	IIC Slave Routines - these use the chip\'s IIC hardware<BR>\
;--------------------------------------------------------------------------<BR>\
	<BR>\
;<BR>\
;<BR>\
; On IIC int<BR>\
;  if Sbit<BR>\
;	   if D/~A == A  ; address<BR>\
;		if R/~W == R ; Call readFirst - slave must write byte to be read into SSPBUF , Could reset state machine.<BR>\
;		if R/~W == W ; Call writeFirst - slave could read Address use it, It will hold SCL low while processing byte.<BR>\
;<BR>\
;	   if D/~A == D  ; data<BR>\
;		if R/~W == R ; Call readNext - slave must write byte to be read into SSPBUF<BR>\
;		if R/~W == W ; Call writeNext - slave must read byte and use, It will hold SCL low while processing byte.<BR>\
;<BR>\
;  if Pbit<BR>\
;	 ; iic bus has gone idle <BR>\
;	 Obviously Master should only send when Bus has seen Stop<BR>\
;<BR>\
; writeFirst<BR>\
; <BR>\
;<BR>\
;<BR>\
<BR>\
IICslave<BR>\
	; IIC int flag has been set so process byte.<BR>\
	<BR>\
	; Write: lowercase done by master<BR>\
	; start, addr + w, ACK, data, ACK , data , ACK , stop<BR>\
	<BR>\
	; Read: UPPERCASE done by SLAVE<BR>\
	; start, addr + r, ACK, DATA, ack , DATA , ack , stop<BR>\
	<BR>\
	call 	iicslaveProcessStart<BR>\
	<BR>\
	banksel  SSPSTAT	<BR>\
	BTFSC	SSPSTAT,S<BR>\
	GOTO	IICslaveStart<BR>\
<BR>\
    ; test if stop detected<BR>\
	BTFSC	SSPSTAT,P<BR>\
	CALL	IICslaveProcessStop<BR>\
	GOTO	iicslaveEndRtn<BR>\
<BR>\
<BR>\
iicslaveEndRtn<BR>\
	banksel	PIR1<BR>\
	BCF		PIR1,SSPIF<BR>\
	RETURN<BR>\
	<BR>\
	<BR>\
IICslaveStart<BR>\
	banksel SSPSTAT	<BR>\
	<BR>\
	BTFSC	SSPSTAT,D_A<BR>\
	GOTO	IICslaveData<BR>\
	GOTO	IICslaveAddress<BR>\
	<BR>\
	<BR>\
IICslaveAddress<BR>\
	;<BR>\
	; Address by seen, use this to reset state machine.<BR>\
	;<BR>\
	;<BR>\
<BR>\
	; D_A = ADDR<BR>\
	; if R_W = W then write <BR>\
	; if R_W = R then READ and first byte needs to be read.	<BR>\
	banksel 	SSPBUF<BR>\
	movfw	SSPBUF<BR>\
	<BR>\
	; store received byte.<BR>\
	banksel	IICtmpWrite<BR>\
	MOVWF	IICtmpWrite<BR>\
<BR>\
	call 	iicslaveProcessAddressByte<BR>\
	<BR>\
	banksel	SSPSTAT<BR>\
	BTFSS	SSPSTAT,R_W<BR>\
	GOTO	IICslaveAddress2<BR>\
<BR>\
	;<BR>\
	; ADDRESS - READ<BR>\
	; 	<BR>\
	;<BR>\
	; need to start READ and write to SSPBUFF<BR>\
	;<BR>\
	call 	iicslaveProcessAddressRead<BR>\
	<BR>\
	banksel 	SSPBUF<BR>\
	movwf	SSPBUF<BR>\
<BR>\
	;<BR>\
	; Byte ready to be send remove clamp on clock to allow master to clock chip.<BR>\
	;<BR>\
	banksel 	SSPCON<BR>\
	BSF		SSPCON,CKP<BR>\
<BR>\
	GOTO	iicslaveEndRtn<BR>\
	<BR>\
	<BR>\
IICslaveAddress2<BR>\
	;<BR>\
	; ADDRESS - WRITE<BR>\
	; 	<BR>\
	call 	iicslaveProcessAddressWrite<BR>\
	GOTO	iicslaveEndRtn<BR>\
<BR>\
	<BR>\
<BR>\
IICslaveData<BR>\
	BTFSC	SSPSTAT,R_W<BR>\
	GOTO IICslaveDataRead<BR>\
	<BR>\
IICslaveDataWrite<BR>\
	;<BR>\
	; chip is being written to so read byte.<BR>\
	;<BR>\
	<BR>\
	banksel  SSPBUF<BR>\
	movfw	SSPBUF<BR>\
	call	iicslaveProcessWriteByte<BR>\
	GOTO	iicslaveEndRtn<BR>\
<BR>\
	<BR>\
IICslaveDataRead<BR>\
	;<BR>\
	; chip is being read so supply byte to be read.<BR>\
	; Test SSPCON.CKP - <BR>\
	;  If it is still high the last byte was NACK\'d<BR>\
	;  Therefore do not send another byte.<BR>\
	;  <BR>\
	; banksel 	SSPCON<BR>\
	; BTFSC	SSPCON,CKP<BR>\
	; GOTO	iicslaveEndRtn<BR>\
	; carry on and write next byte to be sent to master.<BR>\
	;<BR>\
<BR>\
	call	iicslaveProcessReadByte<BR>\
<BR>\
	banksel SSPBUF<BR>\
	movwf	SSPBUF<BR>\
	<BR>\
	;<BR>\
	; Byte ready to be send remove clamp on clock to allow master to clock chip.<BR>\
	;<BR>\
	banksel SSPCON<BR>\
	BSF		SSPCON,CKP<BR>\
	<BR>\
	GOTO	iicslaveEndRtn<BR>\
<BR>\
<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 5.6b 	IIC Slave call back rouines - write these to do what you want<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
iicslaveProcessStart<BR>\
<BR>\
    ;slave:<BR>\
    ;	IIC<BR>\
<BR>\
	<BR>\
	MOVLW	\'#\'<BR>\
	CALL 	RStxChar<BR>\
	MOVLW	\'I\'<BR>\
	CALL 	RStxChar<BR>\
	MOVLW	\'I\'<BR>\
	CALL 	RStxChar<BR>\
	MOVLW	\'C\'<BR>\
	CALL 	RStxChar<BR>\
	MOVLW	\'-\'<BR>\
	CALL 	RStxChar<BR>\
	<BR>\
	goto 	iicslaveProcessEnd<BR>\
<BR>\
;     RETURN<BR>\
<BR>\
<BR>\
iicslaveProcessAddressByte<BR>\
	movlw 	\'@\'<BR>\
	CALL 	RStxChar<BR>\
<BR>\
	MOVFW	IICtmpWrite<BR>\
	<BR>\
	goto 	iicslaveProcessEndData<BR>\
<BR>\
<BR>\
iicslaveProcessAddressWrite<BR>\
    ;<BR>\
    ; Address with Write Set<BR>\
    ;<BR>\
    ; reset Write state machine<BR>\
    ;<BR>\
	RETURN<BR>\
	<BR>\
<BR>\
iicslaveProcessAddressRead<BR>\
    ;<BR>\
    ; Address with Read Set<BR>\
    ;<BR>\
    ; reset read state machine<BR>\
    ;<BR>\
	banksel 	IICslaveDataSource<BR>\
	clrf	IICslaveDataSource<BR>\
	movfw	IICslaveDataSource<BR>\
	RETURN<BR>\
<BR>\
<BR>\
iicslaveProcessWriteByte<BR>\
	movwf IICslaveDataSink<BR>\
<BR>\
	; write out received byte to serial port.<BR>\
	; normally you should call a state machine to sink the received bytes.<BR>\
	;<BR>\
	movlw 	\'W\'<BR>\
	CALL 	RStxChar<BR>\
<BR>\
	MOVFW	IICslaveDataSink<BR>\
	<BR>\
	goto 	iicslaveProcessEndData<BR>\
<BR>\
	<BR>\
<BR>\
iicslaveProcessReadByte<BR>\
	; simulate an data soucre buy incrementing a byte and writing this into SSPBUFF<BR>\
	; You should call a state machine to supply reall information here.<BR>\
<BR>\
	banksel	IICslaveDataSource<BR>\
	incf	IICslaveDataSource,f<BR>\
	<BR>\
	movlw 	\'R\'<BR>\
	CALL 	RStxChar<BR>\
<BR>\
	movfw   IICslaveDataSource	<BR>\
	<BR>\
	CALL 	iicslaveProcessEndData<BR>\
	<BR>\
	movfw    IICslaveDataSource	<BR>\
	<BR>\
	return<BR>\
<BR>\
<BR>\
IICslaveProcessStop<BR>\
	;<BR>\
	; stop bit <BR>\
	;<BR>\
<BR>\
	movlw 	\'s\'<BR>\
	CALL 	RStxChar<BR>\
	<BR>\
	movlw 	\'t\'<BR>\
	CALL 	RStxChar<BR>\
<BR>\
	goto 	iicslaveProcessEndCR<BR>\
	<BR>\
<BR>\
iicslaveProcessEndData<BR>\
<BR>\
	MOVWF IICtmpWrite2<BR>\
<BR>\
	movlw 	\'[\'<BR>\
	CALL 	RStxChar<BR>\
	<BR>\
<BR>\
	SWAPF	IICtmpWrite2,W<BR>\
	CALL	RSwrtHexNibble	<BR>\
<BR>\
	MOVFW	IICtmpWrite2<BR>\
	CALL	RSwrtHexNibble	<BR>\
<BR>\
	movlw 	\']\'<BR>\
	CALL 	RStxChar<BR>\
	<BR>\
	; fall through<BR>\
<BR>\
iicslaveProcessEndCR<BR>\
<BR>\
	MOVLW	0x0D<BR>\
	CALL 	RStxChar<BR>\
		<BR>\
	MOVLW	0x0A<BR>\
	CALL 	RStxChar<BR>\
	; fall through<BR>\
<BR>\
iicslaveProcessEnd<BR>\
<BR>\
	RETURN<BR>\
<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 5.7 	Serial Output Format Routines<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
RSasciiToNibble<BR>\
	MOVWF	RSin<BR>\
	; if 0..1 then 0x30 to 0x39<BR>\
	; if A..F then 0x41 to 0x46<BR>\
	; if a..f then 0x61 to 0x66<BR>\
	; test if bit 4 set and assume a letter or number<BR>\
	BTFSS	RSin,4<BR>\
	ADDLW	0x09		; letter so add 9 <BR>\
	ANDLW	0x0F		; mask of nibble<BR>\
	return<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","email","Wed, 21 May 2008 07:41:39 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - overview ",
"userfield2",
"userfield3",
"userfield4",
"IICslave<BR>\
	; IIC int flag has been set so process byte.<BR>\
	<BR>\
	; Write: lowercase done by master<BR>\
	; start, addr + w, ACK, data, ACK , data , ACK , stop<BR>\
	<BR>\
	; Read: UPPERCASE done by SLAVE<BR>\
	; start, addr + r, ACK, DATA, ack , DATA , ack , stop<BR>\
	<BR>\
	call 	iicslaveProcessStart<BR>\
	<BR>\
	banksel  SSPSTAT	<BR>\
	BTFSC	SSPSTAT,S<BR>\
	GOTO	IICslaveStart<BR>\
<BR>\
    ; test if stop detected<BR>\
	BTFSC	SSPSTAT,P<BR>\
	CALL	IICslaveProcessStop<BR>\
	GOTO	iicslaveEndRtn<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Thu, 7 Aug 2008 22:50:15 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - 16F84 master",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
<BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;The IIC memory protocol is: <BR>\
;<BR>\
; START:<BR>\
; SCL: -----\\__<BR>\
; SDA: --\\_____<BR>\
;<BR>\
; STOP:<BR>\
; SCL: _____/--<BR>\
; SDA: __/-----<BR>\
;<BR>\
; 0:<BR>\
; SCL: __/--\\__<BR>\
; SDA: ________<BR>\
;<BR>\
; 1:<BR>\
; SCL: __/--\\__<BR>\
; SDA: /------\\<BR>\
;<BR>\
;<BR>\
;NOTE: Capitals means SDA asserted by Master, <BR>\
;<BR>\
;little letters means SDA asserted by slave <BR>\
;<BR>\
;SCL asserted by Master and Slave and clocked by Master, <BR>\
;<BR>\
;If SCL does not go to high, maybe SLAVE is asserting SCL to strech SCL pulse. <BR>\
;<BR>\
;<BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;	 START IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;	 START IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC16 IIC memory read:<BR>\
;	 START IICADDR+MEMADDRH+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory read:<BR>\
;	 START IICADDR+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;Some functions to interface iic memory. <BR>\
;The iic memory chips can be written to and read from. <BR>\
;<BR>\
;They need some form of file manager. <BR>\
;<BR>\
;Only one file can be open at once. <BR>\
;<BR>\
;<BR>\
; open    - restore pointers<BR>\
; read    - get byte, increment pointer<BR>\
; write   - write byte, increment pointer<BR>\
; flush   - stops and writes<BR>\
; seekEnd - sets read pointer at start, <BR>\
; close   - save pointers in non volatile store<BR>\
;<BR>\
;<BR>\
;<BR>\
; read pointer  - two octets that contain current read address in iic memory<BR>\
; write pointer - two octets that contain current write address in iic memory<BR>\
;<BR>\
;<BR>\
; if iic buss is started use the pointers to set the address of the memory location to be read.<BR>\
;<BR>\
;<BR>\
; Interface routines for writing one byte:<BR>\
;<BR>\
; K5EEputOneByte - put DATA @ ADDRH+ADDRL<BR>\
;<BR>\
; Interface routines for writing many bytes:<BR>\
;<BR>\
; 	K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; 	follow by DATA using<BR>\
; 	K3EEputAnotherByte<BR>\
; 	and finally a <BR>\
; 	K1EEsendStopBit<BR>\
;<BR>\
; Interface routines for reading bytes:<BR>\
;<BR>\
; 	CALL K3EEstartRead<BR>\
;	<BR>\
;	 <BR>\
;<BR>\
; Interface routines for writing:<BR>\
;<BR>\
; K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; follow by DATA using<BR>\
; K3EEputAnotherByte<BR>\
; and finally a <BR>\
; K1EEsendStopBit<BR>\
<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
; K3EEstartRead  <BR>\
;<BR>\
;	CALL K3EEsetAddr<BR>\
;	CALL K3EEstartRead<BR>\
;	CALL K5EEgetAnotherByte  - sends ACK to memory	<BR>\
;	process,a finally<BR>\
;	CALL K5EEgetLastByte	  - sends NACK to memory	<BR>\
;<BR>\
;	CALL K1EEsendStopBit<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
		 <BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;	Serial Eprom routines<BR>\
;   <BR>\
;<BR>\
; CMDW = 0xA0 + addrH * 2<BR>\
; CMDR = 0xA1 + addrH * 2<BR>\
;<BR>\
;<BR>\
; S CMDW A ADDRL S							Write Address<BR>\
;<BR>\
; Bigger Memories 24L16<BR>\
;<BR>\
; a = slave acks<BR>\
; A = MASTER acks<BR>\
;<BR>\
;<BR>\
; data = slave asserts SDA <BR>\
; DATA = master asserts SDA<BR>\
;<BR>\
;<BR>\
; IIC bus pushes data into the chip and pulls data out. The MAster Pulls data out.<BR>\
;<BR>\
; S CMDW a ADDRL a DATA a S					Write Address and data<BR>\
; S CMDW a ADDRL a DATA a DATA a S			Write Address and data<BR>\
; S CMDR A data A data A .... A data NACK S	Read one to many bytes<BR>\
;<BR>\
; Bigger Memories 24L65<BR>\
;<BR>\
; S CMDW A ADDR A ADDRL A DATA S				Write Address and data<BR>\
; S CMDW A ADDR A ADDRL A DATA A DATA S		Write Address and data<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
;<BR>\
; K0EEsendStartBit<BR>\
; K1EEsendStopBit<BR>\
; K2EEclkCycle<BR>\
; K7EEslaveACKCycle<BR>\
; K8EEdelay8<BR>\
;<BR>\
; K4EEwrtByte		<BR>\
; K6EEreadByte<BR>\
; <BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
; K3EEsetAddr<BR>\
; K5EEputOneByte<BR>\
; K3EEputAnotherByte<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
; K3EEstartRead<BR>\
; K5EEgetOneByte<BR>\
; K5EEgetAnotherByte	<BR>\
; K5EEgetLastByte	<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
; K3EEincAddr - increment EEprt<BR>\
; K3EEsetAddrToW<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
<BR>\
K0EEsendStartBit<BR>\
<BR>\
		; SCL -<BR>\
		; SDA -<BR>\
		; If already high, then this is okay.<BR>\
		;<BR>\
		; Set data and clock high so as not to do a stop.<BR>\
		;<BR>\
		; SDA ___--|---_______<BR>\
		; SCL ____-|------____<BR>\
		;          | START<BR>\
<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSDA<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		<BR>\
		; Now Pull SDA low, while SCL is still high.<BR>\
		; SCL --<BR>\
		; SDA -_<BR>\
		;BCF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
<BR>\
		; SCL K--_<BR>\
		; SDA K-__<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		RETURN<BR>\
<BR>\
;**************<BR>\
; Apply Stop Condition - SDA goes to high while SCL high<BR>\
K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
		<BR>\
		; SDA ___--|--<BR>\
		; SCL _----|--<BR>\
		;     STOP | <BR>\
<BR>\
<BR>\
;		BCF	PORTEEPROM,EEPROMsda<BR>\
;		CALL	K8delay8<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
		<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSDA<BR>\
<BR>\
		<BR>\
		RETURN<BR>\
		<BR>\
;**************<BR>\
;Do Clock Pulse<BR>\
K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;Do ACK byte from memory<BR>\
;Really the PIC should test the response from the memory<BR>\
;The Memory will assert a zero to ACK<BR>\
; Here the PIC also sets the SDA low.<BR>\
; If is set it to high, then the memory would pull it low.<BR>\
K7EEslaveACKCycle<BR>\
<BR>\
		; SDA ___ZZZZZZ_____<BR>\
		; SCL ____----______<BR>\
		;     <BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		CALL	K8delay8<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		;	Should really test for device Asserting ACK.<BR>\
		<BR>\
		;<BR>\
		; need a flag ACKFLAG bit 0 reflects last ACK<BR>\
		;<BR>\
<BR>\
		BCF		ACKFLAG,0<BR>\
		BTFSC	PORTEEPROM,EEPROMsda<BR>\
		BSF		ACKFLAG,0<BR>\
<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K8EEsetSCL<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSCL<BR>\
		BCF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEsetSDA<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSDA<BR>\
		BCF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K8delay8<BR>\
    		MOVLW	0x01<BR>\
		<BR>\
		MOVWF	DELL<BR>\
K8delay8_1	DECFSZ	DELL,f		; 1<BR>\
		GOTO	K8delay8_1		; 2 clk<BR>\
		CLRWDT<BR>\
		RETURN<BR>\
<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Transmit 8 bits in W to EEPROM<BR>\
K4EEwrtByte		<BR>\
		; SCL K4_-_-_-_-_-_-_-_-<BR>\
		; SDA K4x=x=x=x=x=x=x=x=<BR>\
		;       7 6 5 4 3 2 1 0<BR>\
		MOVWF	TRAM<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
K40<BR>\
		BTFSS   TRAM,BIT7<BR>\
		GOTO	K41<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		GOTO	K42<BR>\
K41		BCF		PORTEEPROM,EEPROMsda		<BR>\
K42	 	CALL	K8delay8<BR>\
		; Clock bit<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		CALL	K8delay8<BR>\
		BCF		PORTEEPROM,EEPROMscl 	<BR>\
		CALL 	K8delay8<BR>\
<BR>\
		; push the next bit into <BR>\
		RLF		TRAM,f		<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K40<BR>\
<BR>\
		; Clock the last bit around<BR>\
		RLF		TRAM,f		<BR>\
				<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;***************<BR>\
; Read in DDATA from EEPROM<BR>\
; It does not do the ACK or NACK<BR>\
;   ACK if another byte is to be got<BR>\
;   NACK if this is the last byte to be read<BR>\
;<BR>\
K6EEreadByte<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
		CALL 	K8delay8				<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		; Most signifficant bit first<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
		<BR>\
		<BR>\
K60		<BR>\
		;<BR>\
		; SDA should be at the correct level before SCL is set high<BR>\
		; test SDA <BR>\
		;<BR>\
		<BR>\
		BTFSS	PORTEEPROM,EEPROMsda<BR>\
		GOTO	K61<BR>\
		BSF		STATUS,C<BR>\
		GOTO	K62<BR>\
K61		BCF		STATUS,C<BR>\
<BR>\
<BR>\
K62		<BR>\
		; push the next bit into place<BR>\
		RLF		DDATA,f		<BR>\
		CALL	K8delay8<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
<BR>\
<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL 	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
<BR>\
<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K60<BR>\
<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      <BR>\
		BCF		STATUS,RP0     <BR>\
		<BR>\
		CALL	K8delay8<BR>\
;		MOVFW	DDATA<BR>\
		RETURN<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;<BR>\
;	EEsetAddr send the CWORD and set the address<BR>\
;   <BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;<BR>\
;	 START, IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;<BR>\
;	 START, IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVF	ADDRH,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
		; write ADDRL<BR>\
		MOVFW	ADDRL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		; return 	zero if ACK, non zero if NACK<BR>\
		BCF		STATUS,Z      <BR>\
		BTFSC	ACKFLAG,0<BR>\
		BSF		STATUS,Z      <BR>\
		<BR>\
		RETURN		<BR>\
<BR>\
<BR>\
		<BR>\
;	EEputByte<BR>\
;<BR>\
;	write byte in DDATA to eeprom at the current address, also increment address.<BR>\
;<BR>\
; S CMDW A ADDRL A DATA S					Write Address and data<BR>\
; S CMDW A ADDRL A ADDRL A DATA S					Write Address and data<BR>\
;  <BR>\
<BR>\
K5EEputOneByte<BR>\
		;<BR>\
		; Put one byte and stops transfer<BR>\
		; EEPROM[ ADDR ] = DDATA<BR>\
		;<BR>\
		CALL	K3EEsetAddr<BR>\
		<BR>\
		; SCL K1-_<BR>\
		; SDA K2??<BR>\
         ; Transmit 8 bits<BR>\
<BR>\
		; write DATA<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
                ; Apply Stop Condition<BR>\
		CALL	K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
<BR>\
<BR>\
<BR>\
		CALL	Delay5ms<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
K3EEputAnotherByte<BR>\
		;<BR>\
		; put the data into the chip, also increment local copy of EEprom Address<BR>\
		;<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
		<BR>\
K3EEstartRead<BR>\
		; possibly - finish off last read<BR>\
		; Apply Start<BR>\
		; finished writing address<BR>\
<BR>\
		; now start again<BR>\
		; only send Command word with R<BR>\
		<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16	<BR>\
		;<BR>\
		; The address is composed of ADDRH and ADDRL <BR>\
		;<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E	<BR>\
		ADDLW	0xA1<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		RETURN		<BR>\
		<BR>\
		<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
K5EEgetOneByte<BR>\
		; read the byte at ADDR and increment ADDR<BR>\
		; S CMDW A ADDRH A ADDRL S 	Read one to many bytes<BR>\
		; S CMDR A DATA A DATA A .... A DATA S  	Read one to many bytes<BR>\
		CALL 	K3EEsetAddr<BR>\
		CALL	K3EEstartRead<BR>\
		; haven written the address now start the read<BR>\
		CALL K5EEgetAnotherByte	<BR>\
		CALL K1EEsendStopBit<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEgetAnotherByte	<BR>\
		; read DDATA from EEPROM<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send ACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BCF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
K5EEgetLastByte	<BR>\
		; read DDATA from EEPROM<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send NACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BSF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
<BR>\
<BR>\
K3EEincAddr<BR>\
		; Increment ADDRH:ADDRL<BR>\
		; return with Z = 0 if at end 	<BR>\
<BR>\
		; Increment address<BR>\
		; If at end of memory, then Z is true<BR>\
		;<BR>\
		INCF	ADDRL,F<BR>\
		SKPZ<BR>\
		RETURN		; return non zero<BR>\
<BR>\
		INCF	ADDRH,f<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
		; when B3 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,3<BR>\
	endif	<BR>\
<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		; when B5 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,5<BR>\
	endif	<BR>\
<BR>\
		; BTFSS X,X 	  ; If dc or Bit 5 then Z must be clear.			<BR>\
		BSF		STATUS,Z  ; use the Z bit to indicate end of memory	<BR>\
		RETURN<BR>\
		; End of Memory<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddrToW<BR>\
		; Set ADDRH:ADDRL = 0:W	<BR>\
		;<BR>\
		; ADDRL  = W<BR>\
		; ADDRH = 0<BR>\
		;<BR>\
		<BR>\
		MOVWF	ADDRL<BR>\
		CLRF	ADDRH<BR>\
		RETURN<BR>\
<BR>\
;-----------------------------<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Sat, 9 Aug 2008 09:33:36 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - 16F84 master 2",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;The IIC memory protocol is: <BR>\
;<BR>\
; START:<BR>\
; SCL: -----\\__<BR>\
; SDA: --\\_____<BR>\
;<BR>\
; STOP:<BR>\
; SCL: _____/--<BR>\
; SDA: __/-----<BR>\
;<BR>\
; 0:<BR>\
; SCL: __/--\\__<BR>\
; SDA: ________<BR>\
;<BR>\
; 1:<BR>\
; SCL: __/--\\__<BR>\
; SDA: /------\\<BR>\
;<BR>\
;<BR>\
;NOTE: Capitals means SDA asserted by Master, <BR>\
;<BR>\
;little letters means SDA asserted by slave <BR>\
;<BR>\
;SCL asserted by Master and Slave and clocked by Master, <BR>\
;<BR>\
;If SCL does not go to high, maybe SLAVE is asserting SCL to strech SCL pulse. <BR>\
;<BR>\
;<BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;	 START IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;	 START IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC16 IIC memory read:<BR>\
;	 START IICADDR+MEMADDRH+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory read:<BR>\
;	 START IICADDR+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;Some functions to interface iic memory. <BR>\
;The iic memory chips can be written to and read from. <BR>\
;<BR>\
;They need some form of file manager. <BR>\
;<BR>\
;Only one file can be open at once. <BR>\
;<BR>\
;<BR>\
; open    - restore pointers<BR>\
; read    - get byte, increment pointer<BR>\
; write   - write byte, increment pointer<BR>\
; flush   - stops and writes<BR>\
; seekEnd - sets read pointer at start, <BR>\
; close   - save pointers in non volatile store<BR>\
;<BR>\
;<BR>\
;<BR>\
; read pointer  - two octets that contain current read address in iic memory<BR>\
; write pointer - two octets that contain current write address in iic memory<BR>\
;<BR>\
;<BR>\
; if iic buss is started use the pointers to set the address of the memory location to be read.<BR>\
;<BR>\
;<BR>\
; Interface routines for writing one byte:<BR>\
;<BR>\
; K5EEputOneByte - put DATA @ ADDRH+ADDRL<BR>\
;<BR>\
; Interface routines for writing many bytes:<BR>\
;<BR>\
; 	K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; 	follow by DATA using<BR>\
; 	K3EEputAnotherByte<BR>\
; 	and finally a <BR>\
; 	K1EEsendStopBit<BR>\
;<BR>\
; Interface routines for reading bytes:<BR>\
;<BR>\
; 	CALL K3EEstartRead<BR>\
;	<BR>\
;	 <BR>\
;<BR>\
; Interface routines for writing:<BR>\
;<BR>\
; K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; follow by DATA using<BR>\
; K3EEputAnotherByte<BR>\
; and finally a <BR>\
; K1EEsendStopBit<BR>\
<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
; K3EEstartRead  <BR>\
;<BR>\
;	CALL K3EEsetAddr<BR>\
;	CALL K3EEstartRead<BR>\
;	CALL K5EEgetAnotherByte  - sends ACK to memory	<BR>\
;	process,a finally<BR>\
;	CALL K5EEgetLastByte	  - sends NACK to memory	<BR>\
;<BR>\
;	CALL K1EEsendStopBit<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
		 <BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;	Serial Eprom routines<BR>\
;   <BR>\
;<BR>\
; CMDW = 0xA0 + addrH * 2<BR>\
; CMDR = 0xA1 + addrH * 2<BR>\
;<BR>\
;<BR>\
; S CMDW A ADDRL S							Write Address<BR>\
;<BR>\
; Bigger Memories 24L16<BR>\
;<BR>\
; a = slave acks<BR>\
; A = MASTER acks<BR>\
;<BR>\
;<BR>\
; data = slave asserts SDA <BR>\
; DATA = master asserts SDA<BR>\
;<BR>\
;<BR>\
; IIC bus pushes data into the chip and pulls data out. The MAster Pulls data out.<BR>\
;<BR>\
; S CMDW a ADDRL a DATA a S					Write Address and data<BR>\
; S CMDW a ADDRL a DATA a DATA a S			Write Address and data<BR>\
; S CMDR A data A data A .... A data NACK S	Read one to many bytes<BR>\
;<BR>\
; Bigger Memories 24L65<BR>\
;<BR>\
; S CMDW A ADDR A ADDRL A DATA S				Write Address and data<BR>\
; S CMDW A ADDR A ADDRL A DATA A DATA S		Write Address and data<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
;<BR>\
; K0EEsendStartBit<BR>\
; K1EEsendStopBit<BR>\
; K2EEclkCycle<BR>\
; K7EEslaveACKCycle<BR>\
; K8EEdelay8<BR>\
;<BR>\
; K4EEwrtByte		<BR>\
; K6EEreadByte<BR>\
; <BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
; K3EEsetAddr<BR>\
; K3EEputAnotherByte<BR>\
; K5EEputOneByte<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
; K3EEstartRead<BR>\
; K5EEgetOneByte<BR>\
; K5EEgetAnotherByte	<BR>\
; K5EEgetLastByte	<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
; K3EEincAddr - increment EEprt<BR>\
; K3EEsetAddrToW<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
<BR>\
K0EEsendStartBit<BR>\
<BR>\
		; SCL -<BR>\
		; SDA -<BR>\
		; If already high, then this is okay.<BR>\
		;<BR>\
		; Set data and clock high so as not to do a stop.<BR>\
		;<BR>\
		; SDA ___--|---_______<BR>\
		; SCL ____-|------____<BR>\
		;          | START<BR>\
		CALL	K8EEsetSDA<BR>\
		CALL	K8EEsetSCL<BR>\
		<BR>\
		; Now Pull SDA low, while SCL is still high.<BR>\
		; SCL --<BR>\
		; SDA -_<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
		; SCL K--_<BR>\
		; SDA K-__<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
;**************<BR>\
; Apply Stop Condition - SDA goes to high while SCL high<BR>\
K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
		<BR>\
		; SDA ___--|--<BR>\
		; SCL _----|--<BR>\
		;     STOP | <BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEsetSDA<BR>\
		RETURN<BR>\
		<BR>\
;**************<BR>\
;Do Clock Pulse<BR>\
K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;Do ACK byte from memory<BR>\
;Really the PIC should test the response from the memory<BR>\
;The Memory will assert a zero to ACK<BR>\
; Here the PIC also sets the SDA low.<BR>\
; If is set it to high, then the memory would pull it low.<BR>\
K7EEslaveACKCycle<BR>\
<BR>\
		; SDA ___ZZZZZZ_____<BR>\
		; SCL ____----______<BR>\
		;     <BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		CALL	K8delay8<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		;	Should really test for device Asserting ACK.<BR>\
		<BR>\
		;<BR>\
		; need a flag ACKFLAG bit 0 reflects last ACK<BR>\
		;<BR>\
<BR>\
		BCF		ACKFLAG,0<BR>\
		BTFSC	PORTEEPROM,EEPROMsda<BR>\
		BSF		ACKFLAG,0<BR>\
<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K8EEsetSCL<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSCL<BR>\
		BCF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEsetSDA<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSDA<BR>\
		BCF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
K8delay8<BR>\
		; use goto $1 to padd delay to 10us<BR>\
		goto	$+1<BR>\
		CLRWDT<BR>\
		RETURN<BR>\
<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Transmit 8 bits in W to EEPROM<BR>\
K4EEwrtByte		<BR>\
		; SCL K4_-_-_-_-_-_-_-_-<BR>\
		; SDA K4x=x=x=x=x=x=x=x=<BR>\
		;       7 6 5 4 3 2 1 0<BR>\
		MOVWF	TRAM<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
K40<BR>\
		; call test to save on gotos<BR>\
		call	K4EEwrtByteTestTram		<BR>\
<BR>\
		; Clock bit _---___<BR>\
		call	K8EEsetSCL<BR>\
		call	K8EEresetSCL<BR>\
<BR>\
		; push the next bit into <BR>\
		RLF		TRAM,f		<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K40<BR>\
<BR>\
		; Clock the last bit around<BR>\
		RLF		TRAM,f		<BR>\
				<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K4EEwrtByteTestTram		<BR>\
		; this is called to optimise use of goto s<BR>\
		BTFSS   TRAM,BIT7<BR>\
		goto	K8EEresetSDA<BR>\
		goto	K8EEsetSDA<BR>\
<BR>\
<BR>\
<BR>\
;***************<BR>\
; Read in DDATA from EEPROM<BR>\
; It does not do the ACK or NACK<BR>\
;   ACK if another byte is to be got<BR>\
;   NACK if this is the last byte to be read<BR>\
;<BR>\
K6EEreadByte<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
		CALL 	K8delay8				<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		; Most signifficant bit first<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
		<BR>\
		<BR>\
K60		<BR>\
		;<BR>\
		; SDA should be at the correct level before SCL is set high<BR>\
		; test SDA <BR>\
		;<BR>\
<BR>\
		; ADD 0xFF to EEPROMsda bit and cause a carry, if EEPROMsda is 1<BR>\
		; test EEPROMsda and put it into C bit is status<BR>\
		<BR>\
		MOVFW	PORTEEPROM<BR>\
		ANDLW	1 << EEPROMsda<BR>\
		ADDLW	0xFF<BR>\
		<BR>\
		; push the next bit into place<BR>\
		RLF		DDATA,f		<BR>\
		CALL	K8delay8<BR>\
<BR>\
		;<BR>\
		; SCL	_--___<BR>\
		;<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K60<BR>\
<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      <BR>\
		BCF		STATUS,RP0     <BR>\
		<BR>\
		CALL	K8delay8<BR>\
;		MOVFW	DDATA<BR>\
		RETURN<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;<BR>\
;	EEsetAddr send the CWORD and set the address<BR>\
;   <BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;<BR>\
;	 START, IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;<BR>\
;	 START, IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVF	ADDRH,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
		; write ADDRL<BR>\
		MOVFW	ADDRL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		; return 	zero if ACK, non zero if NACK<BR>\
		BCF		STATUS,Z      <BR>\
		BTFSC	ACKFLAG,0<BR>\
		BSF		STATUS,Z      <BR>\
		<BR>\
		RETURN		<BR>\
<BR>\
<BR>\
		<BR>\
;	EEputByte<BR>\
;<BR>\
;	write byte in DDATA to eeprom at the current address, also increment address.<BR>\
;<BR>\
; S CMDW A ADDRL A DATA S					Write Address and data<BR>\
; S CMDW A ADDRL A ADDRL A DATA S					Write Address and data<BR>\
;  <BR>\
<BR>\
<BR>\
<BR>\
K3EEputAnotherByte<BR>\
		;<BR>\
		; put the data into the chip, also increment local copy of EEprom Address<BR>\
		;<BR>\
		;<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEputOneByte<BR>\
		;<BR>\
		; Put one byte and stops transfer<BR>\
		; EEPROM[ ADDR ] = DDATA<BR>\
		;<BR>\
		; Improvement suggestion: test if SLAVE ACKS transfer.<BR>\
		;<BR>\
		CALL	K3EEsetAddr<BR>\
		; If the Slave does not ACK, then <BR>\
		<BR>\
		; SCL K1-_<BR>\
		; SDA K2??<BR>\
         ; Transmit 8 bits<BR>\
<BR>\
		; write DATA<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		; If the Slave does not ACK, then <BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
                ; Apply Stop Condition<BR>\
		CALL	K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
<BR>\
<BR>\
<BR>\
		CALL	Delay5ms<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
		<BR>\
K3EEstartRead<BR>\
		; possibly - finish off last read<BR>\
		; Apply Start<BR>\
		; finished writing address<BR>\
<BR>\
		; now start again<BR>\
		; only send Command word with R<BR>\
		<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16	<BR>\
		;<BR>\
		; The address is composed of ADDRH and ADDRL <BR>\
		;<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E	<BR>\
		ADDLW	0xA1<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		RETURN		<BR>\
		<BR>\
		<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
K5EEgetOneByte<BR>\
		; read the byte at ADDR and increment ADDR<BR>\
		; S CMDW A ADDRH A ADDRL S 	Read one to many bytes<BR>\
		; S CMDR A DATA A DATA A .... A DATA S  	Read one to many bytes<BR>\
		CALL 	K3EEsetAddr<BR>\
		CALL	K3EEstartRead<BR>\
		; haven written the address now start the read<BR>\
		CALL K5EEgetAnotherByte	<BR>\
		CALL K1EEsendStopBit<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEgetAnotherByte	<BR>\
		; read DDATA from EEPROM<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send ACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BCF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
K5EEgetLastByte	<BR>\
		; read DDATA from EEPROM<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send NACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BSF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
<BR>\
<BR>\
K3EEincAddr<BR>\
		; Increment ADDRH:ADDRL<BR>\
		; return with Z = 0 if at end 	<BR>\
<BR>\
		; Increment address<BR>\
		; If at end of memory, then Z is true<BR>\
		;<BR>\
		INCF	ADDRL,F<BR>\
		SKPZ<BR>\
		RETURN		; return non zero<BR>\
<BR>\
		INCF	ADDRH,f<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
		; when B3 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,3<BR>\
	endif	<BR>\
<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		; when B5 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,5<BR>\
	endif	<BR>\
<BR>\
		; BTFSS X,X 	  ; If dc or Bit 5 then Z must be clear.			<BR>\
		BSF		STATUS,Z  ; use the Z bit to indicate end of memory	<BR>\
		RETURN<BR>\
		; End of Memory<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddrToW<BR>\
		; Set ADDRH:ADDRL = 0:W	<BR>\
		;<BR>\
		; ADDRL  = W<BR>\
		; ADDRH = 0<BR>\
		;<BR>\
		<BR>\
		MOVWF	ADDRL<BR>\
		CLRF	ADDRH<BR>\
		RETURN<BR>\
<BR>\
;-----------------------------<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Sat, 9 Aug 2008 09:42:08 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - 16F84 master",
"userfield2",
"userfield3",
"userfield4",
"name said on Thu, 7 Aug 2008 22:50:15 UTC+0100:<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;The IIC memory protocol is: <BR>\
;<BR>\
; START:<BR>\
; SCL: -----\\__<BR>\
; SDA: --\\_____<BR>\
;<BR>\
; STOP:<BR>\
; SCL: _____/--<BR>\
; SDA: __/-----<BR>\
;<BR>\
; 0:<BR>\
; SCL: __/--\\__<BR>\
; SDA: ________<BR>\
;<BR>\
; 1:<BR>\
; SCL: __/--\\__<BR>\
; SDA: /------\\<BR>\
;<BR>\
;<BR>\
;NOTE: Capitals means SDA asserted by Master, <BR>\
;<BR>\
;little letters means SDA asserted by slave <BR>\
;<BR>\
;SCL asserted by Master and Slave and clocked by Master, <BR>\
;<BR>\
;If SCL does not go to high, maybe SLAVE is asserting SCL to strech SCL pulse. <BR>\
;<BR>\
;<BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;	 START IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;	 START IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC16 IIC memory read:<BR>\
;	 START IICADDR+MEMADDRH+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory read:<BR>\
;	 START IICADDR+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;Some functions to interface iic memory. <BR>\
;The iic memory chips can be written to and read from. <BR>\
;<BR>\
;They need some form of file manager. <BR>\
;<BR>\
;Only one file can be open at once. <BR>\
;<BR>\
;<BR>\
; open    - restore pointers<BR>\
; read    - get byte, increment pointer<BR>\
; write   - write byte, increment pointer<BR>\
; flush   - stops and writes<BR>\
; seekEnd - sets read pointer at start, <BR>\
; close   - save pointers in non volatile store<BR>\
;<BR>\
;<BR>\
;<BR>\
; read pointer  - two octets that contain current read address in iic memory<BR>\
; write pointer - two octets that contain current write address in iic memory<BR>\
;<BR>\
;<BR>\
; if iic buss is started use the pointers to set the address of the memory location to be read.<BR>\
;<BR>\
;<BR>\
; Interface routines for writing one byte:<BR>\
;<BR>\
; K5EEputOneByte - put DATA @ ADDRH+ADDRL<BR>\
;<BR>\
; Interface routines for writing many bytes:<BR>\
;<BR>\
; 	K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; 	follow by DATA using<BR>\
; 	K3EEputAnotherByte<BR>\
; 	and finally a <BR>\
; 	K1EEsendStopBit<BR>\
;<BR>\
; Interface routines for reading bytes:<BR>\
;<BR>\
; 	CALL K3EEstartRead<BR>\
;	<BR>\
;	 <BR>\
;<BR>\
; Interface routines for writing:<BR>\
;<BR>\
; K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; follow by DATA using<BR>\
; K3EEputAnotherByte<BR>\
; and finally a <BR>\
; K1EEsendStopBit<BR>\
<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
; K3EEstartRead  <BR>\
;<BR>\
;	CALL K3EEsetAddr<BR>\
;	CALL K3EEstartRead<BR>\
;	CALL K5EEgetAnotherByte  - sends ACK to memory	<BR>\
;	process,a finally<BR>\
;	CALL K5EEgetLastByte	  - sends NACK to memory	<BR>\
;<BR>\
;	CALL K1EEsendStopBit<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
		 <BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;	Serial Eprom routines<BR>\
;   <BR>\
;<BR>\
; CMDW = 0xA0 + addrH * 2<BR>\
; CMDR = 0xA1 + addrH * 2<BR>\
;<BR>\
;<BR>\
; S CMDW A ADDRL S							Write Address<BR>\
;<BR>\
; Bigger Memories 24L16<BR>\
;<BR>\
; a = slave acks<BR>\
; A = MASTER acks<BR>\
;<BR>\
;<BR>\
; data = slave asserts SDA <BR>\
; DATA = master asserts SDA<BR>\
;<BR>\
;<BR>\
; IIC bus pushes data into the chip and pulls data out. The MAster Pulls data out.<BR>\
;<BR>\
; S CMDW a ADDRL a DATA a S					Write Address and data<BR>\
; S CMDW a ADDRL a DATA a DATA a S			Write Address and data<BR>\
; S CMDR A data A data A .... A data NACK S	Read one to many bytes<BR>\
;<BR>\
; Bigger Memories 24L65<BR>\
;<BR>\
; S CMDW A ADDR A ADDRL A DATA S				Write Address and data<BR>\
; S CMDW A ADDR A ADDRL A DATA A DATA S		Write Address and data<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
;<BR>\
; K0EEsendStartBit<BR>\
; K1EEsendStopBit<BR>\
; K2EEclkCycle<BR>\
; K7EEslaveACKCycle<BR>\
; K8EEdelay8<BR>\
;<BR>\
; K4EEwrtByte		<BR>\
; K6EEreadByte<BR>\
; <BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
; K3EEsetAddr<BR>\
; K5EEputOneByte<BR>\
; K3EEputAnotherByte<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
; K3EEstartRead<BR>\
; K5EEgetOneByte<BR>\
; K5EEgetAnotherByte	<BR>\
; K5EEgetLastByte	<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
; K3EEincAddr - increment EEprt<BR>\
; K3EEsetAddrToW<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
<BR>\
K0EEsendStartBit<BR>\
<BR>\
		; SCL -<BR>\
		; SDA -<BR>\
		; If already high, then this is okay.<BR>\
		;<BR>\
		; Set data and clock high so as not to do a stop.<BR>\
		;<BR>\
		; SDA ___--|---_______<BR>\
		; SCL ____-|------____<BR>\
		;          | START<BR>\
<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSDA<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		<BR>\
		; Now Pull SDA low, while SCL is still high.<BR>\
		; SCL --<BR>\
		; SDA -_<BR>\
		;BCF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
<BR>\
		; SCL K--_<BR>\
		; SDA K-__<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		RETURN<BR>\
<BR>\
;**************<BR>\
; Apply Stop Condition - SDA goes to high while SCL high<BR>\
K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
		<BR>\
		; SDA ___--|--<BR>\
		; SCL _----|--<BR>\
		;     STOP | <BR>\
<BR>\
<BR>\
;		BCF	PORTEEPROM,EEPROMsda<BR>\
;		CALL	K8delay8<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
		<BR>\
		<BR>\
		;BSF		PORTEEPROM,EEPROMsda	<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSDA<BR>\
<BR>\
		<BR>\
		RETURN<BR>\
		<BR>\
;**************<BR>\
;Do Clock Pulse<BR>\
K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;Do ACK byte from memory<BR>\
;Really the PIC should test the response from the memory<BR>\
;The Memory will assert a zero to ACK<BR>\
; Here the PIC also sets the SDA low.<BR>\
; If is set it to high, then the memory would pull it low.<BR>\
K7EEslaveACKCycle<BR>\
<BR>\
		; SDA ___ZZZZZZ_____<BR>\
		; SCL ____----______<BR>\
		;     <BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		CALL	K8delay8<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		;	Should really test for device Asserting ACK.<BR>\
		<BR>\
		;<BR>\
		; need a flag ACKFLAG bit 0 reflects last ACK<BR>\
		;<BR>\
<BR>\
		BCF		ACKFLAG,0<BR>\
		BTFSC	PORTEEPROM,EEPROMsda<BR>\
		BSF		ACKFLAG,0<BR>\
<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K8EEsetSCL<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSCL<BR>\
		BCF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEsetSDA<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSDA<BR>\
		BCF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K8delay8<BR>\
    		MOVLW	0x01<BR>\
		<BR>\
		MOVWF	DELL<BR>\
K8delay8_1	DECFSZ	DELL,f		; 1<BR>\
		GOTO	K8delay8_1		; 2 clk<BR>\
		CLRWDT<BR>\
		RETURN<BR>\
<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Transmit 8 bits in W to EEPROM<BR>\
K4EEwrtByte		<BR>\
		; SCL K4_-_-_-_-_-_-_-_-<BR>\
		; SDA K4x=x=x=x=x=x=x=x=<BR>\
		;       7 6 5 4 3 2 1 0<BR>\
		MOVWF	TRAM<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
K40<BR>\
		BTFSS   TRAM,BIT7<BR>\
		GOTO	K41<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		GOTO	K42<BR>\
K41		BCF		PORTEEPROM,EEPROMsda		<BR>\
K42	 	CALL	K8delay8<BR>\
		; Clock bit<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		CALL	K8delay8<BR>\
		BCF		PORTEEPROM,EEPROMscl 	<BR>\
		CALL 	K8delay8<BR>\
<BR>\
		; push the next bit into <BR>\
		RLF		TRAM,f		<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K40<BR>\
<BR>\
		; Clock the last bit around<BR>\
		RLF		TRAM,f		<BR>\
				<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;***************<BR>\
; Read in DDATA from EEPROM<BR>\
; It does not do the ACK or NACK<BR>\
;   ACK if another byte is to be got<BR>\
;   NACK if this is the last byte to be read<BR>\
;<BR>\
K6EEreadByte<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
		CALL 	K8delay8				<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		; Most signifficant bit first<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
		<BR>\
		<BR>\
K60		<BR>\
		;<BR>\
		; SDA should be at the correct level before SCL is set high<BR>\
		; test SDA <BR>\
		;<BR>\
		<BR>\
		BTFSS	PORTEEPROM,EEPROMsda<BR>\
		GOTO	K61<BR>\
		BSF		STATUS,C<BR>\
		GOTO	K62<BR>\
K61		BCF		STATUS,C<BR>\
<BR>\
<BR>\
K62		<BR>\
		; push the next bit into place<BR>\
		RLF		DDATA,f		<BR>\
		CALL	K8delay8<BR>\
<BR>\
		;BSF		PORTEEPROM,EEPROMscl<BR>\
		;CALL	K8delay8<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
<BR>\
<BR>\
		;BCF		PORTEEPROM,EEPROMscl<BR>\
		;CALL 	K8delay8<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
<BR>\
<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K60<BR>\
<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      <BR>\
		BCF		STATUS,RP0     <BR>\
		<BR>\
		CALL	K8delay8<BR>\
;		MOVFW	DDATA<BR>\
		RETURN<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;<BR>\
;	EEsetAddr send the CWORD and set the address<BR>\
;   <BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;<BR>\
;	 START, IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;<BR>\
;	 START, IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVF	ADDRH,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
		; write ADDRL<BR>\
		MOVFW	ADDRL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		; return 	zero if ACK, non zero if NACK<BR>\
		BCF		STATUS,Z      <BR>\
		BTFSC	ACKFLAG,0<BR>\
		BSF		STATUS,Z      <BR>\
		<BR>\
		RETURN		<BR>\
<BR>\
<BR>\
		<BR>\
;	EEputByte<BR>\
;<BR>\
;	write byte in DDATA to eeprom at the current address, also increment address.<BR>\
;<BR>\
; S CMDW A ADDRL A DATA S					Write Address and data<BR>\
; S CMDW A ADDRL A ADDRL A DATA S					Write Address and data<BR>\
;  <BR>\
<BR>\
K5EEputOneByte<BR>\
		;<BR>\
		; Put one byte and stops transfer<BR>\
		; EEPROM[ ADDR ] = DDATA<BR>\
		;<BR>\
		CALL	K3EEsetAddr<BR>\
		<BR>\
		; SCL K1-_<BR>\
		; SDA K2??<BR>\
         ; Transmit 8 bits<BR>\
<BR>\
		; write DATA<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
                ; Apply Stop Condition<BR>\
		CALL	K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
<BR>\
<BR>\
<BR>\
		CALL	Delay5ms<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
K3EEputAnotherByte<BR>\
		;<BR>\
		; put the data into the chip, also increment local copy of EEprom Address<BR>\
		;<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
		<BR>\
K3EEstartRead<BR>\
		; possibly - finish off last read<BR>\
		; Apply Start<BR>\
		; finished writing address<BR>\
<BR>\
		; now start again<BR>\
		; only send Command word with R<BR>\
		<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16	<BR>\
		;<BR>\
		; The address is composed of ADDRH and ADDRL <BR>\
		;<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E	<BR>\
		ADDLW	0xA1<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		RETURN		<BR>\
		<BR>\
		<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
K5EEgetOneByte<BR>\
		; read the byte at ADDR and increment ADDR<BR>\
		; S CMDW A ADDRH A ADDRL S 	Read one to many bytes<BR>\
		; S CMDR A DATA A DATA A .... A DATA S  	Read one to many bytes<BR>\
		CALL 	K3EEsetAddr<BR>\
		CALL	K3EEstartRead<BR>\
		; haven written the address now start the read<BR>\
		;CALL 	K5EEgetAnotherByte	<BR>\
		CALL 	K5EEgetLastByte<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEgetAnotherByte	<BR>\
		; read DDATA from EEPROM<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send ACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BCF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
K5EEgetLastByte	<BR>\
		; read DDATA from EEPROM<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send NACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BSF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
<BR>\
<BR>\
K3EEincAddr<BR>\
		; Increment ADDRH:ADDRL<BR>\
		; return with Z = 0 if at end 	<BR>\
<BR>\
		; Increment address<BR>\
		; If at end of memory, then Z is true<BR>\
		;<BR>\
		INCF	ADDRL,F<BR>\
		SKPZ<BR>\
		RETURN		; return non zero<BR>\
<BR>\
		INCF	ADDRH,f<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
		; when B3 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,3<BR>\
	endif	<BR>\
<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		; when B5 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,5<BR>\
	endif	<BR>\
<BR>\
		; BTFSS X,X 	  ; If dc or Bit 5 then Z must be clear.			<BR>\
		BSF		STATUS,Z  ; use the Z bit to indicate end of memory	<BR>\
		RETURN<BR>\
		; End of Memory<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddrToW<BR>\
		; Set ADDRH:ADDRL = 0:W	<BR>\
		;<BR>\
		; ADDRL  = W<BR>\
		; ADDRH = 0<BR>\
		;<BR>\
		<BR>\
		MOVWF	ADDRL<BR>\
		CLRF	ADDRH<BR>\
		RETURN<BR>\
<BR>\
;-----------------------------<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Sat, 9 Aug 2008 09:43:09 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - 16F84 master 2",
"userfield2",
"userfield3",
"userfield4",
"name said on Sat, 9 Aug 2008 09:33:36 UTC+0100:<BR>\
<BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;The IIC memory protocol is: <BR>\
;<BR>\
; START:<BR>\
; SCL: -----\\__<BR>\
; SDA: --\\_____<BR>\
;<BR>\
; STOP:<BR>\
; SCL: _____/--<BR>\
; SDA: __/-----<BR>\
;<BR>\
; 0:<BR>\
; SCL: __/--\\__<BR>\
; SDA: ________<BR>\
;<BR>\
; 1:<BR>\
; SCL: __/--\\__<BR>\
; SDA: /------\\<BR>\
;<BR>\
;<BR>\
;NOTE: Capitals means SDA asserted by Master, <BR>\
;<BR>\
;little letters means SDA asserted by slave <BR>\
;<BR>\
;SCL asserted by Master and Slave and clocked by Master, <BR>\
;<BR>\
;If SCL does not go to high, maybe SLAVE is asserting SCL to strech SCL pulse. <BR>\
;<BR>\
;<BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;	 START IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;	 START IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC16 IIC memory read:<BR>\
;	 START IICADDR+MEMADDRH+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory read:<BR>\
;	 START IICADDR+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;Some functions to interface iic memory. <BR>\
;The iic memory chips can be written to and read from. <BR>\
;<BR>\
;They need some form of file manager. <BR>\
;<BR>\
;Only one file can be open at once. <BR>\
;<BR>\
;<BR>\
; open    - restore pointers<BR>\
; read    - get byte, increment pointer<BR>\
; write   - write byte, increment pointer<BR>\
; flush   - stops and writes<BR>\
; seekEnd - sets read pointer at start, <BR>\
; close   - save pointers in non volatile store<BR>\
;<BR>\
;<BR>\
;<BR>\
; read pointer  - two octets that contain current read address in iic memory<BR>\
; write pointer - two octets that contain current write address in iic memory<BR>\
;<BR>\
;<BR>\
; if iic buss is started use the pointers to set the address of the memory location to be read.<BR>\
;<BR>\
;<BR>\
; Interface routines for writing one byte:<BR>\
;<BR>\
; K5EEputOneByte - put DATA @ ADDRH+ADDRL<BR>\
;<BR>\
; Interface routines for writing many bytes:<BR>\
;<BR>\
; 	K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; 	follow by DATA using<BR>\
; 	K3EEputAnotherByte<BR>\
; 	and finally a <BR>\
; 	K1EEsendStopBit<BR>\
;<BR>\
; Interface routines for reading bytes:<BR>\
;<BR>\
; 	CALL K3EEstartRead<BR>\
;	<BR>\
;	 <BR>\
;<BR>\
; Interface routines for writing:<BR>\
;<BR>\
; K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; follow by DATA using<BR>\
; K3EEputAnotherByte<BR>\
; and finally a <BR>\
; K1EEsendStopBit<BR>\
<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
; K3EEstartRead  <BR>\
;<BR>\
;	CALL K3EEsetAddr<BR>\
;	CALL K3EEstartRead<BR>\
;	CALL K5EEgetAnotherByte  - sends ACK to memory	<BR>\
;	process,a finally<BR>\
;	CALL K5EEgetLastByte	  - sends NACK to memory	<BR>\
;<BR>\
;	CALL K1EEsendStopBit<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
		 <BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;	Serial Eprom routines<BR>\
;   <BR>\
;<BR>\
; CMDW = 0xA0 + addrH * 2<BR>\
; CMDR = 0xA1 + addrH * 2<BR>\
;<BR>\
;<BR>\
; S CMDW A ADDRL S							Write Address<BR>\
;<BR>\
; Bigger Memories 24L16<BR>\
;<BR>\
; a = slave acks<BR>\
; A = MASTER acks<BR>\
;<BR>\
;<BR>\
; data = slave asserts SDA <BR>\
; DATA = master asserts SDA<BR>\
;<BR>\
;<BR>\
; IIC bus pushes data into the chip and pulls data out. The MAster Pulls data out.<BR>\
;<BR>\
; S CMDW a ADDRL a DATA a S					Write Address and data<BR>\
; S CMDW a ADDRL a DATA a DATA a S			Write Address and data<BR>\
; S CMDR A data A data A .... A data NACK S	Read one to many bytes<BR>\
;<BR>\
; Bigger Memories 24L65<BR>\
;<BR>\
; S CMDW A ADDR A ADDRL A DATA S				Write Address and data<BR>\
; S CMDW A ADDR A ADDRL A DATA A DATA S		Write Address and data<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
;<BR>\
; K0EEsendStartBit<BR>\
; K1EEsendStopBit<BR>\
; K2EEclkCycle<BR>\
; K7EEslaveACKCycle<BR>\
; K8EEdelay8<BR>\
;<BR>\
; K4EEwrtByte		<BR>\
; K6EEreadByte<BR>\
; <BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
; K3EEsetAddr<BR>\
; K3EEputAnotherByte<BR>\
; K5EEputOneByte<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
; K3EEstartRead<BR>\
; K5EEgetOneByte<BR>\
; K5EEgetAnotherByte	<BR>\
; K5EEgetLastByte	<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
; K3EEincAddr - increment EEprt<BR>\
; K3EEsetAddrToW<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
<BR>\
K0EEsendStartBit<BR>\
<BR>\
		; SCL -<BR>\
		; SDA -<BR>\
		; If already high, then this is okay.<BR>\
		;<BR>\
		; Set data and clock high so as not to do a stop.<BR>\
		;<BR>\
		; SDA ___--|---_______<BR>\
		; SCL ____-|------____<BR>\
		;          | START<BR>\
		CALL	K8EEsetSDA<BR>\
		CALL	K8EEsetSCL<BR>\
		<BR>\
		; Now Pull SDA low, while SCL is still high.<BR>\
		; SCL --<BR>\
		; SDA -_<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
		; SCL K--_<BR>\
		; SDA K-__<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
;**************<BR>\
; Apply Stop Condition - SDA goes to high while SCL high<BR>\
K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
		<BR>\
		; SDA ___--|--<BR>\
		; SCL _----|--<BR>\
		;     STOP | <BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEsetSDA<BR>\
		RETURN<BR>\
		<BR>\
;**************<BR>\
;Do Clock Pulse<BR>\
K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;Do ACK byte from memory<BR>\
;Really the PIC should test the response from the memory<BR>\
;The Memory will assert a zero to ACK<BR>\
; Here the PIC also sets the SDA low.<BR>\
; If is set it to high, then the memory would pull it low.<BR>\
K7EEslaveACKCycle<BR>\
<BR>\
		; SDA ___ZZZZZZ_____<BR>\
		; SCL ____----______<BR>\
		;     <BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		CALL	K8delay8<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		;	Should really test for device Asserting ACK.<BR>\
		<BR>\
		;<BR>\
		; need a flag ACKFLAG bit 0 reflects last ACK<BR>\
		;<BR>\
<BR>\
		BCF		ACKFLAG,0<BR>\
		BTFSC	PORTEEPROM,EEPROMsda<BR>\
		BSF		ACKFLAG,0<BR>\
<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		; make data ouput again<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
<BR>\
		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K8EEsetSCL<BR>\
		BSF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSCL<BR>\
		BCF		PORTEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEsetSDA<BR>\
		BSF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSDA<BR>\
		BCF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
K8delay8<BR>\
		; use goto $1 to padd delay to 10us<BR>\
		goto	$+1<BR>\
		CLRWDT<BR>\
		RETURN<BR>\
<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Transmit 8 bits in W to EEPROM<BR>\
K4EEwrtByte		<BR>\
		; SCL K4_-_-_-_-_-_-_-_-<BR>\
		; SDA K4x=x=x=x=x=x=x=x=<BR>\
		;       7 6 5 4 3 2 1 0<BR>\
		MOVWF	TRAM<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
K40<BR>\
		; call test to save on gotos<BR>\
		call	K4EEwrtByteTestTram		<BR>\
<BR>\
		; Clock bit _---___<BR>\
		call	K8EEsetSCL<BR>\
		call	K8EEresetSCL<BR>\
<BR>\
		; push the next bit into <BR>\
		RLF		TRAM,f		<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K40<BR>\
<BR>\
		; Clock the last bit around<BR>\
		RLF		TRAM,f		<BR>\
				<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K4EEwrtByteTestTram		<BR>\
		; this is called to optimise use of goto s<BR>\
		BTFSS   TRAM,BIT7<BR>\
		goto	K8EEresetSDA<BR>\
		goto	K8EEsetSDA<BR>\
<BR>\
<BR>\
<BR>\
;***************<BR>\
; Read in DDATA from EEPROM<BR>\
; It does not do the ACK or NACK<BR>\
;   ACK if another byte is to be got<BR>\
;   NACK if this is the last byte to be read<BR>\
;<BR>\
K6EEreadByte<BR>\
		BSF		STATUS,RP0 	<BR>\
		BSF		TRISEEPROM,EEPROMsda      ; make DDATA port an input<BR>\
		BCF		STATUS,RP0      <BR>\
		CALL 	K8delay8				<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		; Most signifficant bit first<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
		<BR>\
		<BR>\
K60		<BR>\
		;<BR>\
		; SDA should be at the correct level before SCL is set high<BR>\
		; test SDA <BR>\
		;<BR>\
<BR>\
		; ADD 0xFF to EEPROMsda bit and cause a carry, if EEPROMsda is 1<BR>\
		; test EEPROMsda and put it into C bit is status<BR>\
		<BR>\
		MOVFW	PORTEEPROM<BR>\
		ANDLW	1 << EEPROMsda<BR>\
		ADDLW	0xFF<BR>\
		<BR>\
		; push the next bit into place<BR>\
		RLF		DDATA,f		<BR>\
		CALL	K8delay8<BR>\
<BR>\
		;<BR>\
		; SCL	_--___<BR>\
		;<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K60<BR>\
<BR>\
		BSF		STATUS,RP0 	<BR>\
		BCF		TRISEEPROM,EEPROMsda      <BR>\
		BCF		STATUS,RP0     <BR>\
		<BR>\
		CALL	K8delay8<BR>\
;		MOVFW	DDATA<BR>\
		RETURN<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;<BR>\
;	EEsetAddr send the CWORD and set the address<BR>\
;   <BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;<BR>\
;	 START, IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;<BR>\
;	 START, IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVF	ADDRH,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
		; write ADDRL<BR>\
		MOVFW	ADDRL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		; return 	zero if ACK, non zero if NACK<BR>\
		BCF		STATUS,Z      <BR>\
		BTFSC	ACKFLAG,0<BR>\
		BSF		STATUS,Z      <BR>\
		<BR>\
		RETURN		<BR>\
<BR>\
<BR>\
		<BR>\
;	EEputByte<BR>\
;<BR>\
;	write byte in DDATA to eeprom at the current address, also increment address.<BR>\
;<BR>\
; S CMDW A ADDRL A DATA S					Write Address and data<BR>\
; S CMDW A ADDRL A ADDRL A DATA S					Write Address and data<BR>\
;  <BR>\
<BR>\
<BR>\
<BR>\
K3EEputAnotherByte<BR>\
		;<BR>\
		; put the data into the chip, also increment local copy of EEprom Address<BR>\
		;<BR>\
		;<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEputOneByte<BR>\
		;<BR>\
		; Put one byte and stops transfer<BR>\
		; EEPROM[ ADDR ] = DDATA<BR>\
		;<BR>\
		; Improvement suggestion: test if SLAVE ACKS transfer.<BR>\
		;<BR>\
		CALL	K3EEsetAddr<BR>\
		; If the Slave does not ACK, then <BR>\
		<BR>\
		; SCL K1-_<BR>\
		; SDA K2??<BR>\
         ; Transmit 8 bits<BR>\
<BR>\
		; write DATA<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		; If the Slave does not ACK, then <BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
                ; Apply Stop Condition<BR>\
		CALL	K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
<BR>\
<BR>\
<BR>\
		CALL	Delay5ms<BR>\
		GOTO 	K3EEincAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
		<BR>\
K3EEstartRead<BR>\
		; possibly - finish off last read<BR>\
		; Apply Start<BR>\
		; finished writing address<BR>\
<BR>\
		; now start again<BR>\
		; only send Command word with R<BR>\
		<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16	<BR>\
		;<BR>\
		; The address is composed of ADDRH and ADDRL <BR>\
		;<BR>\
		MOVFW	ADDRH<BR>\
		ADDWF	ADDRH,W<BR>\
		ANDLW	0x0E	<BR>\
		ADDLW	0xA1<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		RETURN		<BR>\
		<BR>\
		<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
K5EEgetOneByte<BR>\
		; read the byte at ADDR and increment ADDR<BR>\
		; S CMDW A ADDRH A ADDRL S 	Read one to many bytes<BR>\
		; S CMDR A DATA A DATA A .... A DATA S  	Read one to many bytes<BR>\
		CALL 	K3EEsetAddr<BR>\
		CALL	K3EEstartRead<BR>\
		; haven written the address now start the read<BR>\
		;CALL 	K5EEgetAnotherByte	<BR>\
		CALL 	K5EEgetLastByte<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEgetAnotherByte	<BR>\
		; read DDATA from EEPROM<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send ACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BCF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
K5EEgetLastByte	<BR>\
		; read DDATA from EEPROM<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send NACK to memory<BR>\
		; BSF	PORTEEPROM,EEPROMsda<BR>\
		BSF	PORTEEPROM,EEPROMsda<BR>\
<BR>\
		CALL	K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincAddr<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
<BR>\
<BR>\
K3EEincAddr<BR>\
		; Increment ADDRH:ADDRL<BR>\
		; return with Z = 0 if at end 	<BR>\
<BR>\
		; Increment address<BR>\
		; If at end of memory, then Z is true<BR>\
		;<BR>\
		INCF	ADDRL,F<BR>\
		SKPZ<BR>\
		RETURN		; return non zero<BR>\
<BR>\
		INCF	ADDRH,f<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
		; when B3 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,3<BR>\
	endif	<BR>\
<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		; when B5 is set to 1 then the mem is at the end.<BR>\
		BTFSC	ADDRH,5<BR>\
	endif	<BR>\
<BR>\
		; BTFSS X,X 	  ; If dc or Bit 5 then Z must be clear.			<BR>\
		BSF		STATUS,Z  ; use the Z bit to indicate end of memory	<BR>\
		RETURN<BR>\
		; End of Memory<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetAddrToW<BR>\
		; Set ADDRH:ADDRL = 0:W	<BR>\
		;<BR>\
		; ADDRL  = W<BR>\
		; ADDRH = 0<BR>\
		;<BR>\
		<BR>\
		MOVWF	ADDRL<BR>\
		CLRF	ADDRH<BR>\
		RETURN<BR>\
<BR>\
;-----------------------------<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Sun, 7 Sep 2008 17:54:45 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"IIC - 16F84 master tris3",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;The IIC memory protocol is: <BR>\
;<BR>\
; START:<BR>\
; SCL: -----\\__<BR>\
; SDA: --\\_____<BR>\
;<BR>\
; STOP:<BR>\
; SCL: _____/--<BR>\
; SDA: __/-----<BR>\
;<BR>\
; 0:<BR>\
; SCL: __/--\\__<BR>\
; SDA: ________<BR>\
;<BR>\
; 1:<BR>\
; SCL: __/--\\__<BR>\
; SDA: /------\\<BR>\
;<BR>\
;<BR>\
;NOTE: Capitals means SDA asserted by Master, <BR>\
;<BR>\
;little letters means SDA asserted by slave <BR>\
;<BR>\
;SCL asserted by Master and Slave and clocked by Master, <BR>\
;<BR>\
;If SCL does not go to high, maybe SLAVE is asserting SCL to strech SCL pulse. <BR>\
;<BR>\
;<BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;	 START IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;	 START IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC16 IIC memory read:<BR>\
;	 START IICADDR+MEMADDRH+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory read:<BR>\
;	 START IICADDR+R,ack,data,ACK,data,ACK,data,NACK,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
;<BR>\
;Some functions to interface iic memory. <BR>\
;The iic memory chips can be written to and read from. <BR>\
;<BR>\
;They need some form of file manager. <BR>\
;<BR>\
;Only one file can be open at once. <BR>\
;<BR>\
;<BR>\
; open    - restore pointers<BR>\
; read    - get byte, increment pointer<BR>\
; write   - write byte, increment pointer<BR>\
; flush   - stops and writes<BR>\
; seekEnd - sets read pointer at start, <BR>\
; close   - save pointers in non volatile store<BR>\
;<BR>\
;<BR>\
;<BR>\
; read pointer  - two octets that contain current read address in iic memory<BR>\
; write pointer - two octets that contain current write address in iic memory<BR>\
;<BR>\
; IICwrtPtrH	; IIC memory address incremented by writes <BR>\
; IICwrtPtrL	; <BR>\
;<BR>\
; IICrdPtrH	; IIC memory address incremented by reads<BR>\
; IICrdPtrL	; <BR>\
;<BR>\
;<BR>\
;<BR>\
; if iic buss is started use the pointers to set the address of the memory location to be read.<BR>\
;<BR>\
;<BR>\
; Interface routines for writing one byte:<BR>\
;<BR>\
; K5EEputOneByte - put DATA @ ADDRH+ADDRL<BR>\
;<BR>\
; Interface routines for writing many bytes:<BR>\
;<BR>\
; 	K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; 	follow by DATA using<BR>\
; 	K3EEputAnotherByte<BR>\
; 	and finally a <BR>\
; 	K1EEsendStopBit<BR>\
;<BR>\
; Interface routines for reading bytes:<BR>\
;<BR>\
; 	CALL K3EEstartRead<BR>\
;	<BR>\
;	 <BR>\
;<BR>\
; Interface routines for writing:<BR>\
;<BR>\
; K3EEsetAddr - set memory pointer to ADDRH + ADDRL<BR>\
; follow by DATA using<BR>\
; K3EEputAnotherByte<BR>\
; and finally a <BR>\
; K1EEsendStopBit<BR>\
<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
; K3EEstartRead  <BR>\
;<BR>\
;	CALL K3EEsetAddr<BR>\
;	CALL K3EEstartRead<BR>\
;	CALL K5EEgetAnotherByte  - sends ACK to memory	<BR>\
;	process,a finally<BR>\
;	CALL K5EEgetLastByte	  - sends NACK to memory	<BR>\
;<BR>\
;	CALL K1EEsendStopBit<BR>\
;<BR>\
;<BR>\
<BR>\
<BR>\
		 <BR>\
;************************************************<BR>\
;	Serial Eprom <BR>\
;<BR>\
;**************<BR>\
;<BR>\
;	Serial Eprom routines<BR>\
;   <BR>\
;<BR>\
; CMDW = 0xA0 + addrH * 2<BR>\
; CMDR = 0xA1 + addrH * 2<BR>\
;<BR>\
;<BR>\
; S CMDW A ADDRL S							Write Address<BR>\
;<BR>\
; Bigger Memories 24L16<BR>\
;<BR>\
; a = slave acks<BR>\
; A = MASTER acks<BR>\
;<BR>\
;<BR>\
; data = slave asserts SDA <BR>\
; DATA = master asserts SDA<BR>\
;<BR>\
;<BR>\
; IIC bus pushes data into the chip and pulls data out. The MAster Pulls data out.<BR>\
;<BR>\
; S CMDW a ADDRL a DATA a S					Write Address and data<BR>\
; S CMDW a ADDRL a DATA a DATA a S			Write Address and data<BR>\
; S CMDR A data A data A .... A data NACK S	Read one to many bytes<BR>\
;<BR>\
; Bigger Memories 24L65<BR>\
;<BR>\
; S CMDW A ADDR A ADDRL A DATA S				Write Address and data<BR>\
; S CMDW A ADDR A ADDRL A DATA A DATA S		Write Address and data<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
;<BR>\
; K0EEsendStartBit<BR>\
; K1EEsendStopBit<BR>\
; K2EEclkCycle<BR>\
; K7EEslaveACKCycle<BR>\
; K8EEdelay8<BR>\
;<BR>\
; K4EEwrtByte		<BR>\
; K6EEreadByte<BR>\
; <BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
; K3EEsetWrtAddr<BR>\
; K3EEputAnotherByte<BR>\
; K5EEputOneByte<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
; K3EEstartRead<BR>\
; K5EEgetOneByte<BR>\
; K5EEgetAnotherByte	<BR>\
; K5EEgetLastByte	<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
;<BR>\
; K3EEclrWrtPtr<BR>\
; K3EEclrRdPtr<BR>\
;<BR>\
; K3EEincWrtAddr<BR>\
; K3EEincRdAddr<BR>\
;<BR>\
; K3EEtestWrtAddr		<BR>\
; K3EEcompareRdPrtWrtptr<BR>\
;<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; Low Level routines<BR>\
<BR>\
K0EEsendStartBit<BR>\
<BR>\
		; SCL -<BR>\
		; SDA -<BR>\
		; If already high, then this is okay.<BR>\
		;<BR>\
		; Set data and clock high so as not to do a stop.<BR>\
		;<BR>\
		; SDA ___--|---_______<BR>\
		; SCL ____-|------____<BR>\
		;          | START<BR>\
<BR>\
<BR>\
		CALL	K8EEsetSDA<BR>\
		CALL	K8EEsetSCL<BR>\
		<BR>\
		; Now Pull SDA low, while SCL is still high.<BR>\
		; SCL --<BR>\
		; SDA -_<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
<BR>\
		; SCL K--_<BR>\
		; SDA K-__<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
;**************<BR>\
; Apply Stop Condition - SDA goes to high while SCL high<BR>\
K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
		<BR>\
		; SDA ___--|--<BR>\
		; SCL _----|--<BR>\
		;     STOP | <BR>\
<BR>\
<BR>\
		; pull SDA and SCL low so that stop condition can be applied.<BR>\
		CALL	K8EEresetSCL<BR>\
		CALL	K8EEresetSDA<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEsetSDA<BR>\
		RETURN<BR>\
		<BR>\
;**************<BR>\
;Do Clock Pulse<BR>\
K2EEclkCycle<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;Do ACK byte from memory<BR>\
;Really the PIC should test the response from the memory<BR>\
;The Memory will assert a zero to ACK<BR>\
; Here the PIC also sets the SDA low.<BR>\
; If is set it to high, then the memory would pull it low.<BR>\
K7EEslaveACKCycle<BR>\
		; SDA ___ZZZZZZ_____<BR>\
		; SCL ____----______<BR>\
		;     <BR>\
		; make data ouput again<BR>\
<BR>\
		CALL	K8EEsetSDA<BR>\
		CALL	K8delay8<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
		;	Test for device Asserting ACK.<BR>\
		; return 	zero if ACK, non zero if NACK<BR>\
		; Z set if ACK		<BR>\
		; Z reset if NACK		<BR>\
<BR>\
		banksel	PORTEEPROM<BR>\
		<BR>\
		BCF		STATUS,Z      <BR>\
		BTFSS	PORTEEPROM,EEPROMsda<BR>\
		BSF		STATUS,Z      <BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
<BR>\
		; Z set if ACK		<BR>\
		; Z reset if NACK		<BR>\
		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K8EEsetSCL<BR>\
		banksel 	TRISEEPROM<BR>\
		BSF		TRISEEPROM,EEPROMscl<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSCL<BR>\
		banksel 	TRISEEPROM<BR>\
		BCF		TRISEEPROM,EEPROMscl<BR>\
<BR>\
		banksel 	PORTEEPROM<BR>\
		BCF		PORTEEPROM,EEPROMscl<BR>\
		<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEsetSDA<BR>\
		banksel 	TRISEEPROM<BR>\
		BSF		TRISEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
<BR>\
K8EEresetSDA<BR>\
		banksel 	TRISEEPROM<BR>\
		BCF		TRISEEPROM,EEPROMsda<BR>\
<BR>\
		banksel 	PORTEEPROM<BR>\
		BCF		PORTEEPROM,EEPROMsda<BR>\
		goto	K8delay8<BR>\
<BR>\
K8delay8<BR>\
		; use goto $1 to padd delay to 10us<BR>\
		goto	$+1<BR>\
		goto	$+1<BR>\
		CLRWDT<BR>\
		banksel 	PORTB<BR>\
		RETURN<BR>\
<BR>\
<BR>\
;************************************************<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;************************************************<BR>\
;	Transmit 8 bits in W to EEPROM<BR>\
K4EEwrtByte		<BR>\
		; SCL K4_-_-_-_-_-_-_-_-<BR>\
		; SDA K4x=x=x=x=x=x=x=x=<BR>\
		;       7 6 5 4 3 2 1 0<BR>\
		MOVWF	TRAM<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
K40<BR>\
		; call test to save on gotos<BR>\
		call	K4EEwrtByteTestTram		<BR>\
<BR>\
		; Clock bit _---___<BR>\
		call	K8EEsetSCL<BR>\
		call	K8EEresetSCL<BR>\
<BR>\
		; push the next bit into <BR>\
		RLF		TRAM,f		<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K40<BR>\
<BR>\
		; Clock the last bit around<BR>\
		RLF		TRAM,f		<BR>\
<BR>\
		; Leave SDA high<BR>\
		call	K8EEsetSDA<BR>\
			<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
K4EEwrtByteTestTram		<BR>\
		; this is called to optimise use of gotos<BR>\
		BTFSS   TRAM,BIT7<BR>\
		goto	K8EEresetSDA<BR>\
		goto	K8EEsetSDA<BR>\
<BR>\
<BR>\
<BR>\
;***************<BR>\
; Read in DDATA from EEPROM<BR>\
; It does not do the ACK or NACK<BR>\
;   ACK if another byte is to be got<BR>\
;   NACK if this is the last byte to be read<BR>\
;<BR>\
K6EEreadByte<BR>\
		call	K8EEsetSDA<BR>\
		CALL 	K8delay8				<BR>\
<BR>\
		; now clock 8 bits into the EEPROM<BR>\
		; Most signifficant bit first<BR>\
		movlw	8<BR>\
		movwf	LoopCnt<BR>\
		<BR>\
		<BR>\
K60		<BR>\
		;<BR>\
		; SDA should be at the correct level before SCL is set high<BR>\
		; test SDA <BR>\
		;<BR>\
<BR>\
		; ADD 0xFF to EEPROMsda bit and cause a carry, if EEPROMsda is 1<BR>\
		; test EEPROMsda and put it into C bit is status<BR>\
<BR>\
		banksel	PORTEEPROM		<BR>\
		MOVFW	PORTEEPROM<BR>\
		ANDLW	1 << EEPROMsda<BR>\
		ADDLW	0xFF<BR>\
		<BR>\
		; push the next bit into place<BR>\
		RLF		DDATA,f		<BR>\
		CALL	K8delay8<BR>\
<BR>\
		;<BR>\
		; SCL	_--___<BR>\
		;<BR>\
<BR>\
		CALL	K8EEsetSCL<BR>\
		CALL	K8EEresetSCL<BR>\
<BR>\
		DECFSZ	LoopCnt,f<BR>\
		goto	K60<BR>\
		<BR>\
		CALL	K8delay8<BR>\
		RETURN<BR>\
<BR>\
;************************************************<BR>\
;<BR>\
;	EEsetAddr send the CWORD and set the address<BR>\
;   <BR>\
;	 24LC16 IIC memory set address and write data:<BR>\
;<BR>\
;	 START, IICADDR+MEMADDRH+W,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;	 24LC65 IIC memory set address and write data<BR>\
;<BR>\
;	 START, IICADDR+W,ack,MEMADDRH,ack,MEMADDRL,ack,DATA,ack,DATA,ack,DATA,ack,DATA,ack,STOP<BR>\
;<BR>\
;<BR>\
;<BR>\
<BR>\
;-----------------------------<BR>\
; API level - put bytes <BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K3EEsetWrtAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		;MOVFW	ADDRH <BR>\
		MOVFW	IICwrtPtrH<BR>\
<BR>\
		;ADDWF	ADDRH,W<BR>\
		ADDWF	IICwrtPtrH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC256<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVFW	IICwrtPtrH<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
	ifdef MEM24LC256<BR>\
		MOVFW	IICwrtPtrH<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
<BR>\
		MOVFW	IICwrtPtrL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		; Z set if ACK		<BR>\
		; Z reset if NACK		<BR>\
		RETURN		<BR>\
<BR>\
K3EEsetReadAddr<BR>\
<BR>\
        ; Apply Start, IICADDR + MEMADDRH*2 +W, ack , ADDRL, ack <BR>\
        ;<BR>\
        ; Set Address pointer of chip to ADDRH+ADDRL<BR>\
        ;<BR>\
        ; No Stop condition is set, so more data can be sent.<BR>\
        ;<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16<BR>\
	   	; Double the ADDRH to step over the W/R bit.<BR>\
	   	; Add it to the IICADDR <BR>\
	   	; pins A0,A1,A2 ignored<BR>\
	   	;<BR>\
	   	; MEM24LC16 is 2K and has 8 pages.<BR>\
	   	; Only one  chip can be used on the IIC bus<BR>\
	   	; ADDRH is 3 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
	   	<BR>\
	   	<BR>\
		;MOVFW	ADDRH <BR>\
		MOVFW	IICrdPtrH<BR>\
<BR>\
		;ADDWF	ADDRH,W<BR>\
		ADDWF	IICrdPtrH,W<BR>\
		ANDLW	0x0E<BR>\
		; Add Chip Address	<BR>\
		ADDLW	0xA0<BR>\
		; Add W/R bit W=0<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC256<BR>\
		;<BR>\
		; MEM24LC65 is 64K and has 8 pages.<BR>\
		; pins A0,A1,A2 select the device. Logger only uses one memory<BR>\
		;<BR>\
	   	; Up to 8 chips can be used on the IIC bus<BR>\
	   	; ADDRH is 5 bits<BR>\
	   	; ADDRL is 8 bits<BR>\
<BR>\
		MOVLW	0xA0 ; + chip Address to match A0,A1,A2 pins<BR>\
<BR>\
	endif<BR>\
<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		;<BR>\
		; 24LC65 is has 64K bits or 8K bytes or 32 pages of 256 bytes<BR>\
		;<BR>\
		; write ADDRH<BR>\
		;<BR>\
		MOVFW	IICrdPtrH<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
	ifdef MEM24LC256<BR>\
		MOVFW	IICrdPtrH<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	endif	<BR>\
<BR>\
<BR>\
		MOVFW	IICrdPtrL<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
		<BR>\
		CALL	K1EEsendStopBit<BR>\
<BR>\
		; Z set if ACK		<BR>\
		; Z reset if NACK		<BR>\
		RETURN		<BR>\
<BR>\
		<BR>\
;	EEputByte<BR>\
;<BR>\
;	write byte in DDATA to eeprom at the current address, also increment address.<BR>\
;<BR>\
; S CMDW A ADDRL A DATA S					Write Address and data<BR>\
; S CMDW A ADDRL A ADDRL A DATA S					Write Address and data<BR>\
;  <BR>\
<BR>\
<BR>\
<BR>\
K3EEputAnotherByte<BR>\
		;<BR>\
		; put the data into the chip, also increment local copy of EEprom Address<BR>\
		;<BR>\
		;<BR>\
		; if last memory location, then zero flag set<BR>\
<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		GOTO 	K3EEincWrtAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEputOneByte<BR>\
		;<BR>\
		; Put one byte and stops transfer<BR>\
		; if last memory location, then zero flag set<BR>\
<BR>\
		; EEPROM[ ADDR ] = DDATA<BR>\
		;<BR>\
		; Improvement suggestion: test if SLAVE ACKS transfer.<BR>\
		;<BR>\
		CALL	K3EEsetWrtAddr<BR>\
		; If the Slave does not ACK, then <BR>\
		<BR>\
		; SCL K1-_<BR>\
		; SDA K2??<BR>\
         ; Transmit 8 bits<BR>\
<BR>\
		; write DATA<BR>\
         MOVF		DDATA,W<BR>\
		CALL 	K4EEwrtByte<BR>\
		; If the Slave does not ACK, then <BR>\
		CALL 	K7EEslaveACKCycle<BR>\
	<BR>\
		; SCL K2-_<BR>\
		; SDA K2??<BR>\
                ; Apply Stop Condition<BR>\
		call	K8EEresetSDA<BR>\
		CALL	K1EEsendStopBit<BR>\
		; SCL K1?--<BR>\
		; SDA K1__-<BR>\
<BR>\
<BR>\
<BR>\
		CALL	Delay5ms<BR>\
		GOTO 	K3EEincWrtAddr<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - get bytes <BR>\
<BR>\
		<BR>\
K3EEstartRead<BR>\
		; possibly - finish off last read<BR>\
		; Apply Start<BR>\
		; finished writing address<BR>\
<BR>\
		; now start again<BR>\
		; only send Command word with R<BR>\
		<BR>\
		;<BR>\
		; Copy IICrdPtr<BR>\
		;<BR>\
		<BR>\
		CALL	K0EEsendStartBit<BR>\
<BR>\
	ifdef MEM24LC16	<BR>\
		;<BR>\
		; The address is composed of ADDRH and ADDRL <BR>\
		;<BR>\
		MOVFW	IICrdPtrH<BR>\
		ADDWF	IICrdPtrH,W<BR>\
		ANDLW	0x0E	<BR>\
		ADDLW	0xA1<BR>\
	endif<BR>\
<BR>\
	ifdef MEM24LC65<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
<BR>\
	ifdef MEM24LC256<BR>\
		MOVLW	0xA1<BR>\
	endif<BR>\
<BR>\
		CALL	K4EEwrtByte<BR>\
		CALL 	K7EEslaveACKCycle<BR>\
<BR>\
<BR>\
		; if slave ACK\'s Z set<BR>\
		; if Slave NACK\'d Z reset<BR>\
		<BR>\
		RETURN		<BR>\
		<BR>\
		<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;**************<BR>\
;<BR>\
;	Send START, the control word and<BR>\
;	MOVLW	0xA0		<BR>\
;	MOVWF	CWORD	<BR>\
;	CLRF	ADDRL<BR>\
;	CLRF	ADDRH<BR>\
		<BR>\
K5EEgetOneByte<BR>\
		; read the byte at ADDR and increment ADDR<BR>\
		; S CMDW A ADDRH A ADDRL S 	Read one to many bytes<BR>\
		; S CMDR A DATA A DATA A .... A DATA S  	Read one to many bytes<BR>\
		<BR>\
		; does not test ACK<BR>\
		;<BR>\
		CALL	K3EEsetReadAddr<BR>\
<BR>\
		CALL	K3EEstartRead<BR>\
		; haven written the address now start the read<BR>\
		;CALL 	K5EEgetAnotherByte	<BR>\
		CALL 	K5EEgetLastByte<BR>\
		CALL	K1EEsendStopBit		<BR>\
		RETURN<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
K5EEgetAnotherByte	<BR>\
		; read DDATA from EEPROM<BR>\
		; if last memory location, then zero flag set<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send ACK to memory<BR>\
		CALL	K8EEresetSDA<BR>\
		CALL	K2EEclkCycle<BR>\
		CALL	K8EEsetSDA<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincRdAddr<BR>\
<BR>\
K5EEgetLastByte	<BR>\
		; read DDATA from EEPROM<BR>\
		; if last memory location, then zero flag set<BR>\
<BR>\
<BR>\
		CALL	K6EEreadByte<BR>\
<BR>\
		; send NACK to memory<BR>\
		CALL	K8EEsetSDA<BR>\
		CALL	K2EEclkCycle<BR>\
		CALL	K8EEsetSDA<BR>\
<BR>\
		; SCL K2-_<BR>\
		; SDA K2--<BR>\
		GOTO	K3EEincRdAddr<BR>\
<BR>\
<BR>\
;-----------------------------<BR>\
; API level - memory Prt<BR>\
<BR>\
<BR>\
K3EEclrWrtPtr<BR>\
		clrf	IICwrtPtrH<BR>\
		clrf	IICwrtPtrL<BR>\
		return<BR>\
<BR>\
K3EEclrRdPtr<BR>\
		clrf	IICrdPtrH<BR>\
		clrf	IICrdPtrL<BR>\
		return<BR>\
<BR>\
K3EEincWrtAddr<BR>\
		incfsz	IICwrtPtrL<BR>\
		goto	$+2<BR>\
		incf	IICwrtPtrH,f<BR>\
		goto 	K3EEtestWrtAddr<BR>\
<BR>\
K3EEincRdAddr<BR>\
		incfsz	IICrdPtrL<BR>\
		goto	$+2<BR>\
		incf	IICrdPtrH,f<BR>\
		return<BR>\
<BR>\
		; This is done in upload command.<BR>\
		; so test if rdPrt has got to last wrtPtr<BR>\
		<BR>\
		;<BR>\
		; compare rdPtr and wrtPtr<BR>\
		; IICprtTest has sticky bits if XOR are no zero.<BR>\
		;<BR>\
<BR>\
<BR>\
<BR>\
K3EEcompareRdPrtWrtptr<BR>\
		; returns with status Z set<BR>\
		CLRF	IICprtTest<BR>\
		movfw	IICrdPtrL<BR>\
		xorwf	IICwrtPtrL,w	<BR>\
		iorwf	IICprtTest,f<BR>\
<BR>\
		movfw	IICrdPtrH<BR>\
		xorwf	IICwrtPtrH,w	<BR>\
		iorwf	IICprtTest,f<BR>\
		; if both bytes are zero then Z is set.	<BR>\
		return<BR>\
<BR>\
K3EEtestWrtAddr		<BR>\
<BR>\
<BR>\
		; EEPROM[0] is a bit mask to provide carry<BR>\
		; 0x80<BR>\
	<BR>\
		; 0xF8 	MEM24LC16<BR>\
		; 0xE0 	MEM24LC64<BR>\
		movlw	EE_MAX_WRTH<BR>\
		call	EEread<BR>\
		ADDWF	IICwrtPtrH,w<BR>\
		<BR>\
		;		<BR>\
		; if carry, then end of memory reached.<BR>\
		;<BR>\
				<BR>\
		BTFSC	STATUS,C<BR>\
		; BTFSS X,X 	  ; If dc or Bit 5 then Z must be clear.			<BR>\
		BSF		STATUS,Z  ; use the Z bit to indicate end of memory	<BR>\
<BR>\
		; stop logging at the end of the memory<BR>\
		BTFSC	STATUS,C<BR>\
		call	CLdisableAutoSample<BR>\
		<BR>\
		RETURN<BR>\
		; End of Memory<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Sun, 1 Mar 2009 22:39:15 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"Parity",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
<BR>\
	list      p=16f628            ; list directive to define processor<BR>\
	#include <p16f628.inc>        ; processor specific variable definitions<BR>\
	<BR>\
	__CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _ER_OSC_CLKOUT & _MCLRE_ON & _LVP_ON<BR>\
<BR>\
; \'__CONFIG\' directive is used to embed configuration data within .asm file.<BR>\
; The lables following the directive are located in the respective .inc file.<BR>\
; See respective data sheet for additional information on configuration word.<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
;***** VARIABLE DEFINITIONS<BR>\
w_temp        EQU     0x70        ; variable used for context saving <BR>\
status_temp   EQU     0x71        ; variable used for context saving<BR>\
<BR>\
<BR>\
<BR>\
	cblock	0x20	; 16F628<BR>\
		tmp<BR>\
		cnt <BR>\
	endc<BR>\
<BR>\
<BR>\
;**********************************************************************<BR>\
		ORG     0x000             ; processor reset vector<BR>\
		goto    main              ; go to beginning of program<BR>\
<BR>\
<BR>\
		ORG     0x004             ; interrupt vector location<BR>\
		movwf   w_temp            ; save off current W register contents<BR>\
		movf	STATUS,w          ; move status register into W register<BR>\
		movwf	status_temp       ; save off contents of STATUS register<BR>\
<BR>\
<BR>\
; isr code can go here or be located as a call subroutine elsewhere<BR>\
<BR>\
<BR>\
		movf    status_temp,w     ; retrieve copy of STATUS register<BR>\
		movwf	STATUS            ; restore pre-isr STATUS register contents<BR>\
		swapf   w_temp,f<BR>\
		swapf   w_temp,w          ; restore pre-isr W register contents<BR>\
		retfie                    ; return from interrupt<BR>\
<BR>\
<BR>\
<BR>\
parityWv0<BR>\
<BR>\
		; Find Parity of W , leaving parity in LSB<BR>\
		; bits 7654 3210<BR>\
		;<BR>\
		;<BR>\
		movwf	tmp<BR>\
<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
		<BR>\
		rrf		tmp,f  ; ( b0 xor b1  ) xor b2 => bo<BR>\
		xorwf	tmp,w<BR>\
<BR>\
		rrf		tmp,f  ; ( ( b0 xor b1  ) xor b2 ) xor b3 => bo<BR>\
		xorwf	tmp,w<BR>\
		<BR>\
		; w.b0 no contains parity<BR>\
<BR>\
		andlw	1<BR>\
		return<BR>\
<BR>\
<BR>\
<BR>\
parityWv1<BR>\
<BR>\
		; Find Parity of W , leaving parity in LSB<BR>\
		; bits 7654 3210<BR>\
		;<BR>\
		;<BR>\
		movwf	tmp<BR>\
<BR>\
		; xor nibbles together<BR>\
		swapf	tmp,w<BR>\
		xorwf	tmp,f<BR>\
<BR>\
		; tmp contains nibles exored together.<BR>\
		; xor 4 bits in lsb <BR>\
<BR>\
		; we now have to find the parity of adjacent bits<BR>\
		movfw	tmp<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,w  ; b0 xor b1 => bo<BR>\
		<BR>\
		rrf		tmp,f  ; ( b0 xor b1  ) xor b2 => bo<BR>\
		xorwf	tmp,w<BR>\
<BR>\
		rrf		tmp,f  ; ( ( b0 xor b1  ) xor b2 ) xor b3 => bo<BR>\
		xorwf	tmp,w<BR>\
		<BR>\
		; w.b0 no contains parity<BR>\
<BR>\
		andlw	1<BR>\
		return<BR>\
<BR>\
<BR>\
parityWv2<BR>\
<BR>\
		; Find Parity of W , leaving parity in LSB<BR>\
		; bits 7654 3210<BR>\
		;<BR>\
		;<BR>\
		movwf	tmp<BR>\
<BR>\
		; xor nibbles together<BR>\
		swapf	tmp,w<BR>\
		xorwf	tmp,f<BR>\
<BR>\
		; tmp contains nibles exored together.<BR>\
		; xor 4 bits in lsb <BR>\
<BR>\
		; we now have to find the parity of adjacent bits<BR>\
		movfw	tmp<BR>\
		rrf		tmp,f<BR>\
		rrf		tmp,f<BR>\
		xorwf	tmp,f; b0 xor b1 => bo<BR>\
<BR>\
<BR>\
		movfw	tmp		<BR>\
		rrf		tmp,f  ; ( b0 xor b1  ) xor b2 => bo<BR>\
		xorwf	tmp,w<BR>\
		<BR>\
		; w.b0 no contains parity<BR>\
<BR>\
		andlw	1<BR>\
		return<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
main<BR>\
<BR>\
; remaining code goes here<BR>\
		<BR>\
		clrf	cnt<BR>\
<BR>\
main1<BR>\
		movfw	cnt<BR>\
		call 	parityWv0 ;  20 cycles		<BR>\
<BR>\
		movfw	cnt<BR>\
		call 	parityWv1 ;  15 cycles		<BR>\
<BR>\
		movfw	cnt<BR>\
		call 	parityWv2  ;  15 cycles		<BR>\
<BR>\
		decfsz	cnt<BR>\
		goto	main1<BR>\
						<BR>\
		movwf	tmp	<BR>\
<BR>\
<BR>\
		END                       ; directive \'end of program\'<BR>\
"
);
gbF( // guestbook.pl 
"Doug","","Sat, 28 Mar 2009 08:26:01 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"CRC  for DS18S20",
"",
"",
"",
"This code has still to be verified.<BR>\
<BR>\
<BR>\
	cblock<BR>\
CRCcrc<BR>\
CRCa<BR>\
	endc<BR>\
<BR>\
CRCts<BR>\
<BR>\
;  CRC polynomial for DS18S20 page 8 of 23  <BR>\
;                                                     <BR>\
;   a > [8] > [7] > [6] > [5] > [4]  + a > [3]  + a > [2] > [1] > [0] + i/p > a<BR>\
;                         <BR>\
<BR>\
; ip is in bit 0<BR>\
	; work out a = crc:bit0  xor  i/p <BR>\
	xorwf	CRCcrc,w<BR>\
	andlw	0x01<BR>\
	; fill w with 1s or 0s based on bit 0<BR>\
	xorlw	0x01<BR>\
	addlw	0xFF<BR>\
	; store  A<BR>\
	movwf	CRCa<BR>\
<BR>\
	;<BR>\
	; now prepare crc<BR>\
	;<BR>\
<BR>\
	rrf		CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; work out bit3 xor a <BR>\
	; work out bit2 xor a <BR>\
	;<BR>\
	<BR>\
	movlw 	( 0<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,w<BR>\
	xorwf	CRCa,f<BR>\
<BR>\
	<BR>\
	;<BR>\
	; update CRC but orint new values for bit 7 , bit 3 and bit2.<BR>\
	;<BR>\
<BR>\
	;<BR>\
	;  zero 	bit 7, bit 3, bit 2 in CRC<BR>\
	;<BR>\
	movlw 	~( 1<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; mask of new values for bit 7, bit 3, bit 2 <BR>\
	;<BR>\
	movfw	CRCa	<BR>\
	; add   bit 7, bit 3, bit 2 to CRC<BR>\
	andlw	( 1<<7 | 1<<3  | 1<<2 )<BR>\
	iorwf	CRCcrc,f<BR>\
<BR>\
	return<BR>\
<BR>\
<BR>\
Start<BR>\
<BR>\
	movlw	0xFF<BR>\
	movwf	CRCcrc<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
"
);
gbF( // guestbook.pl 
"name","email","Sat, 28 Mar 2009 08:29:11 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"EE routines for Prog Memory",
"userfield2",
"userfield3",
"userfield4",
"<BR>\
<BR>\
;<BR>\
; EEPROM for program<BR>\
; a - setaddr<BR>\
; e - erase32 words at address.<BR>\
; < - read word and increment<BR>\
; > - write word and increment, needs to write 4 butes at once.<BR>\
;<BR>\
<BR>\
<BR>\
EEsetProgAddr<BR>\
	banksel	RSeeaddrh<BR>\
	movfw   RSeeaddrh	<BR>\
	<BR>\
	banksel	EEADRH<BR>\
	movwf	EEADRH	<BR>\
<BR>\
	banksel	RSeeaddrl<BR>\
	movfw   RSeeaddrl	<BR>\
	<BR>\
	banksel	EEADR<BR>\
	movwf	EEADR	<BR>\
<BR>\
	return<BR>\
<BR>\
EEincProgAddr<BR>\
	banksel	RSeeaddrl<BR>\
	incfsz	RSeeaddrl<BR>\
	goto	$+2<BR>\
	incfsz	RSeeaddrh<BR>\
	return<BR>\
<BR>\
<BR>\
EEprogRead<BR>\
	; w contains address<BR>\
	banksel	EEADR	<BR>\
	movwf	EEADR<BR>\
	banksel 	EECON1<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD; Point to Prog memory<BR>\
	endif<BR>\
	<BR>\
	bsf		EECON1,RD<BR>\
	BANKSEL 	EEDATA ; Select Bank of EEDATA<BR>\
	movfw	EEDATA<BR>\
	banksel	0	<BR>\
	return<BR>\
<BR>\
EEprogWrite	; blocking, EEADR and EEDATA set up.<BR>\
<BR>\
	banksel EECON1<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD ; Point to PROG<BR>\
	endif<BR>\
	BCF 	EECON1, FREE ; Enable Row Erase operation<BR>\
	<BR>\
	bsf		EECON1,WREN<BR>\
	bcf		INTCON,GIE<BR>\
	movlw	0x55<BR>\
	movwf	EECON2<BR>\
	movlw	0xAA<BR>\
	movwf	EECON2<BR>\
	bsf		EECON1,WR<BR>\
	BsF		INTCON,GIE<BR>\
	<BR>\
	; Now wait for EEwrt to finish write<BR>\
EEwaitForProgWrt	; block until EEPROM write has finished.<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
<BR>\
	; NOTE:- I have commented out the goto and the write to eeprom started to work<BR>\
	<BR>\
;	btfsc	EECON1,WR	<BR>\
;	goto	EEwaitForWrt<BR>\
	<BR>\
	;bcf	EECON1,EEIF	; EEPROM finished<BR>\
<BR>\
	banksel	0	<BR>\
	return<BR>\
<BR>\
<BR>\
EEprogErase	; blocking, EEADR and EEDATA set up.<BR>\
<BR>\
	banksel EECON1<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD ; Point to PROG<BR>\
	endif<BR>\
	BSF 	EECON1, FREE ; Enable Row Erase operation<BR>\
	<BR>\
	bsf		EECON1,WREN<BR>\
	bcf		INTCON,GIE<BR>\
	movlw	0x55<BR>\
	movwf	EECON2<BR>\
	movlw	0xAA<BR>\
	movwf	EECON2<BR>\
	bsf		EECON1,WR<BR>\
	BsF		INTCON,GIE<BR>\
	<BR>\
	; Now wait for EEwrt to finish write<BR>\
EEwaitForProgErase	; block until EEPROM write has finished.<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
<BR>\
	; NOTE:- I have commented out the goto and the write to eeprom started to work<BR>\
	<BR>\
;	btfsc	EECON1,WR	<BR>\
;	goto	EEwaitForWrt<BR>\
	<BR>\
	;bcf	EECON1,EEIF	; EEPROM finished<BR>\
<BR>\
	banksel	0	<BR>\
	return<BR>\
<BR>\
<BR>\
<BR>\
; e - erase32<BR>\
; < - read word and increment<BR>\
; > - write word and increment<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Sat, 28 Mar 2009 08:59:21 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"CRC  for DS18S20",
"",
"",
"",
"Doug said on Sat, 28 Mar 2009 08:26:01 UTC+0000:<BR>\
This code has still to be verified.<BR>\
<BR>\
<BR>\
	cblock<BR>\
CRCcrc<BR>\
CRCa<BR>\
	endc<BR>\
<BR>\
CRCts<BR>\
<BR>\
;  CRC polynomial for DS18S20 page 8 of 23  <BR>\
;                                                     <BR>\
;   a > [8] > [7] > [6] > [5] > [4]  + a > [3]  + a > [2] > [1] > [0] + i/p > a<BR>\
;                         <BR>\
<BR>\
; ip is in bit 0<BR>\
	; work out a = crc:bit0  xor  i/p <BR>\
	xorwf	CRCcrc,w<BR>\
	andlw	0x01<BR>\
	; fill w with 1s or 0s based on bit 0<BR>\
	xorlw	0x01<BR>\
	addlw	0xFF<BR>\
	; store  A<BR>\
	movwf	CRCa<BR>\
<BR>\
	;<BR>\
	; now prepare crc<BR>\
	;<BR>\
<BR>\
	rrf		CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; work out bit3 xor a <BR>\
	; work out bit2 xor a <BR>\
	;<BR>\
	<BR>\
	movlw 	( 0<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,w<BR>\
	xorwf	CRCa,f<BR>\
<BR>\
	<BR>\
	;<BR>\
	; update CRC but orint new values for bit 7 , bit 3 and bit2.<BR>\
	;<BR>\
<BR>\
	;<BR>\
	;  zero 	bit 7, bit 3, bit 2 in CRC<BR>\
	;<BR>\
	movlw 	~( 1<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; mask of new values for bit 7, bit 3, bit 2 <BR>\
	;<BR>\
	movfw	CRCa	<BR>\
	; add   bit 7, bit 3, bit 2 to CRC<BR>\
	andlw	( 1<<7 | 1<<3  | 1<<2 )<BR>\
	iorwf	CRCcrc,f<BR>\
<BR>\
	return<BR>\
<BR>\
<BR>\
Start<BR>\
<BR>\
	movlw	0xFF<BR>\
	movwf	CRCcrc<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
"
);
gbF( // guestbook.pl 
"doug","him@me","Sat, 28 Mar 2009 09:57:40 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"Cookie test",
"",
"",
"",
"hkdshfkqhd"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sat, 28 Mar 2009 19:52:41 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"CRC  for DS18S20",
"",
"",
"",
"doug said on Sat, 28 Mar 2009 08:59:21 UTC+0000:<BR>\
Doug said on Sat, 28 Mar 2009 08:26:01 UTC+0000:<BR>\
This code has still to be verified.<BR>\
<BR>\
	cblock<BR>\
CRCcrc<BR>\
CRCa<BR>\
	endc<BR>\
<BR>\
CRCts<BR>\
<BR>\
;  CRC polynomial for DS18S20 page 8 of 23  <BR>\
;                                                     <BR>\
;   a > [8] > [7] > [6] > [5] > [4]  + a > [3]  + a > [2] > [1] > [0] + i/p > a<BR>\
;                         <BR>\
<BR>\
; ip is in bit 0<BR>\
	; work out a = crc:bit0  xor  i/p <BR>\
	xorwf	CRCcrc,w<BR>\
	andlw	0x01<BR>\
	; fill w with 1s or 0s based on bit 0<BR>\
	xorlw	0x01<BR>\
	addlw	0xFF<BR>\
	; store  A<BR>\
	movwf	CRCa<BR>\
<BR>\
	;<BR>\
	; now prepare crc, shift CRC to new position, opens up bit 7 <BR>\
	;<BR>\
<BR>\
	rrf		CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; work out bit3 xor a <BR>\
	; work out bit2 xor a <BR>\
	;<BR>\
	<BR>\
	movlw 	( 0<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,w<BR>\
	xorwf	CRCa,f<BR>\
<BR>\
	<BR>\
	;<BR>\
	; update CRC but orint new values for bit 7 , bit 3 and bit2.<BR>\
	;<BR>\
<BR>\
	;<BR>\
	;  zero 	bit 7, bit 3, bit 2 in CRC<BR>\
	;<BR>\
	movlw 	~( 1<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; mask of new values for bit 7, bit 3, bit 2 <BR>\
	;<BR>\
	movfw	CRCa	<BR>\
	; add   bit 7, bit 3, bit 2 to CRC<BR>\
	andlw	( 1<<7 | 1<<3  | 1<<2 )<BR>\
	iorwf	CRCcrc,f<BR>\
<BR>\
	return<BR>\
<BR>\
<BR>\
Start<BR>\
<BR>\
	movlw	0x00<BR>\
	movwf	CRCcrc<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	0<BR>\
<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	0<BR>\
	call		CRCts<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	0<BR>\
	call		CRCts<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	0<BR>\
	call		CRCts<BR>\
<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
<BR>\
<BR>\
	cblock<BR>\
CRCcrc<BR>\
CRCa<BR>\
	endc<BR>\
<BR>\
CRCts<BR>\
<BR>\
;  CRC polynomial for DS18S20 page 8 of 23  <BR>\
;                                                     <BR>\
;   a > [8] > [7] > [6] > [5] > [4]  + a > [3]  + a > [2] > [1] > [0] + i/p > a<BR>\
;                         <BR>\
<BR>\
; ip is in bit 0<BR>\
	; work out a = crc:bit0  xor  i/p <BR>\
	xorwf	CRCcrc,w<BR>\
	andlw	0x01<BR>\
	; fill w with 1s or 0s based on bit 0<BR>\
	xorlw	0x01<BR>\
	addlw	0xFF<BR>\
	; store  A<BR>\
	movwf	CRCa<BR>\
<BR>\
	;<BR>\
	; now prepare crc<BR>\
	;<BR>\
<BR>\
	rrf		CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; work out bit3 xor a <BR>\
	; work out bit2 xor a <BR>\
	;<BR>\
	<BR>\
	movlw 	( 0<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,w<BR>\
	xorwf	CRCa,f<BR>\
<BR>\
	<BR>\
	;<BR>\
	; update CRC but orint new values for bit 7 , bit 3 and bit2.<BR>\
	;<BR>\
<BR>\
	;<BR>\
	;  zero 	bit 7, bit 3, bit 2 in CRC<BR>\
	;<BR>\
	movlw 	~( 1<<7 | 1<<3  | 1<<2 )<BR>\
	andwf	CRCcrc,f<BR>\
<BR>\
	;<BR>\
	; mask of new values for bit 7, bit 3, bit 2 <BR>\
	;<BR>\
	movfw	CRCa	<BR>\
	; add   bit 7, bit 3, bit 2 to CRC<BR>\
	andlw	( 1<<7 | 1<<3  | 1<<2 )<BR>\
	iorwf	CRCcrc,f<BR>\
<BR>\
	return<BR>\
<BR>\
<BR>\
Start<BR>\
<BR>\
	movlw	0xFF<BR>\
	movwf	CRCcrc<BR>\
<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
	movlw	1<BR>\
	call		CRCts<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sat, 28 Mar 2009 19:54:16 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"CRC  for DS18S20 check",
"",
"",
"",
"JavaScript - run inside a web page.<BR>\
var b = new Array()<BR>\
var newb = new Array()<BR>\
<BR>\
<BR>\
var A,ip;<BR>\
<BR>\
<BR>\
b[0] = 0;<BR>\
b[1] = 0;<BR>\
b[2] = 0;<BR>\
b[3] = 0;<BR>\
b[4] = 0;<BR>\
b[5] = 0;<BR>\
b[6] = 0;<BR>\
b[7] = 0;<BR>\
<BR>\
function crc( ip ) {<BR>\
<BR>\
  a = b[0] ^ip<BR>\
<BR>\
  newb[ 2 ] =  a ^ b[3]<BR>\
  newb[ 3 ] =  a ^ b[4]<BR>\
<BR>\
<BR>\
  b[0] = b[1]<BR>\
  b[1] = b[2]<BR>\
  b[2] = a ^ b[3]<BR>\
  b[3] = a ^ b[4]<BR>\
  b[4] = b[5]<BR>\
  b[5] = b[6]<BR>\
  b[6] = b[7]<BR>\
  b[7] = a<BR>\
<BR>\
  var opStr= \" \" + b[7] + \" \" + b[6] + \" \" + b[5] + \" \" + b[4] + \" \" + b[3] + \" \" + b[2] + \" \" + b[1] + \" \" + b[0] + \"<BR>\" <BR>\
 <BR>\
  var opNum= ( b[7]*128 +  b[6]*64 +  b[5]*32 +  b[4]*16  + b[3]*8 + b[2]*4 + b[1]*2 + b[0] )  <BR>\
<BR>\
  <BR>\
  self.document.write( \" 0x \"+opNum.toString(16) + opStr )<BR>\
<BR>\
<BR>\
}<BR>\
<BR>\
crc(1)<BR>\
crc(0)<BR>\
crc(1)<BR>\
crc(0)<BR>\
crc(1)<BR>\
crc(0)<BR>\
crc(1)<BR>\
crc(0)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
crc(1)<BR>\
<BR>\
<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sat, 28 Mar 2009 19:56:04 UTC+0000","212.56.108.219  | dougrice.plus.com  ",
"CRC  for DS18S20 test",
"",
"",
"",
"I checked this prediction against the MPLAB sequence and they agreed.<BR>\
0x 8c 1 0 0 0 1 1 0 0<BR>\
0x 46 0 1 0 0 0 1 1 0<BR>\
0x af 1 0 1 0 1 1 1 1<BR>\
0x db 1 1 0 1 1 0 1 1<BR>\
0x 6d 0 1 1 0 1 1 0 1<BR>\
0x ba 1 0 1 1 1 0 1 0<BR>\
0x d1 1 1 0 1 0 0 0 1<BR>\
0x e4 1 1 1 0 0 1 0 0<BR>\
0x fe 1 1 1 1 1 1 1 0<BR>\
0x f3 1 1 1 1 0 0 1 1<BR>\
0x 79 0 1 1 1 1 0 0 1<BR>\
0x 3c 0 0 1 1 1 1 0 0<BR>\
0x 92 1 0 0 1 0 0 1 0<BR>\
0x c5 1 1 0 0 0 1 0 1<BR>\
0x 62 0 1 1 0 0 0 1 0<BR>\
0x bd 1 0 1 1 1 1 0 1<BR>\
0x 5e 0 1 0 1 1 1 1 0<BR>\
0x a3 1 0 1 0 0 0 1 1<BR>\
0x 51 0 1 0 1 0 0 0 1<BR>\
0x 28 0 0 1 0 1 0 0 0<BR>\
0x 98 1 0 0 1 1 0 0 0<BR>\
0x c0 1 1 0 0 0 0 0 0<BR>\
0x ec 1 1 1 0 1 1 0 0<BR>\
0x fa 1 1 1 1 1 0 1 0<BR>\
0x f1 1 1 1 1 0 0 0 1<BR>\
0x 78 0 1 1 1 1 0 0 0<BR>\
0x b0 1 0 1 1 0 0 0 0<BR>\
0x d4 1 1 0 1 0 1 0 0<BR>\
0x e6 1 1 1 0 0 1 1 0<BR>\
0x ff 1 1 1 1 1 1 1 1<BR>\
0x 7f 0 1 1 1 1 1 1 1<BR>\
0x 3f 0 0 1 1 1 1 1 1<BR>\
"
);
gbF( // guestbook.pl 
"Doug Rice","doug.h.rice@btinternet.com","Mon, 30 Mar 2009 08:22:19 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"EE routines for Prog Memory",
"",
"",
"",
"<BR>\
;--------------------------------------------------------------------------<BR>\
; Sec 5.10 	EEprom Routines for 16F88<BR>\
;--------------------------------------------------------------------------<BR>\
<BR>\
<BR>\
EEsetProgAddrH<BR>\
	; set up EEADH<BR>\
	banksel	EEADRH<BR>\
	movwf   EEADRH<BR>\
	return<BR>\
	<BR>\
EEsetProgAddrL<BR>\
EEsetAddr<BR>\
	banksel	EEADR<BR>\
	movwf	EEADR<BR>\
	return<BR>\
<BR>\
EEread	<BR>\
	; w contains address<BR>\
	banksel	EEADR	<BR>\
	movwf	EEADR<BR>\
<BR>\
	banksel 	EECON1<BR>\
	ifdef 	EEPGD<BR>\
	bcf 	EECON1, EEPGD; Point to Data memory<BR>\
	endif<BR>\
<BR>\
EEprogReadCommon<BR>\
	<BR>\
	bsf		EECON1,RD<BR>\
	BANKSEL 	EEDATA ; Select Bank of EEDATA<BR>\
	movfw	EEDATA<BR>\
	banksel	0	<BR>\
	return<BR>\
<BR>\
<BR>\
EEprogRead<BR>\
	; Assumes addres is set up<BR>\
<BR>\
	banksel 	EECON1<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD; Point to Prog memory<BR>\
	endif<BR>\
	goto	EEprogReadCommon<BR>\
<BR>\
<BR>\
	<BR>\
	<BR>\
EEprogWrite	; blocking, EEADR and EEDATA set up.<BR>\
	banksel EECON1<BR>\
	bcf		EECON1,WREN		; disable EROM<BR>\
<BR>\
	ifdef	FREE<BR>\
	BCF 	EECON1, FREE ; Disable Row Erase operation<BR>\
	endif<BR>\
<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD 	; Point to PROG<BR>\
	endif<BR>\
<BR>\
	goto	EEwrtCommon<BR>\
	<BR>\
EEprogErase	; blocking, EEADR and EEDATA set up.<BR>\
	banksel EECON1<BR>\
	bcf		EECON1,WREN		; disable EROM<BR>\
<BR>\
	ifdef	FREE<BR>\
	BSF 	EECON1, FREE ; Enable Row Erase operation<BR>\
	endif<BR>\
<BR>\
	ifdef 	EEPGD<BR>\
	bsf 	EECON1, EEPGD ; Point to PROG<BR>\
	endif<BR>\
 <BR>\
	goto	EEwrtCommon<BR>\
	<BR>\
EEwrt	; blocking, EEADR and EEDATA set up.<BR>\
<BR>\
	banksel EEDATA<BR>\
	movwf	EEDATA<BR>\
	;bcf	PIR1,EEIF<BR>\
<BR>\
	banksel EECON1<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
	<BR>\
<BR>\
	ifdef	FREE<BR>\
	BCF 	EECON1, FREE ; Enable Row Erase operation<BR>\
	endif<BR>\
<BR>\
	ifdef 	EEPGD<BR>\
	bcf 	EECON1, EEPGD ; Point to DATA<BR>\
	endif<BR>\
	<BR>\
EEwrtCommon<BR>\
	bsf		EECON1,WREN<BR>\
	bcf		INTCON,GIE<BR>\
	movlw	0x55<BR>\
	movwf	EECON2<BR>\
	movlw	0xAA<BR>\
	movwf	EECON2<BR>\
	bsf		EECON1,WR<BR>\
	BsF		INTCON,GIE<BR>\
	<BR>\
	; Now wait for EEwrt to finish write<BR>\
EEwaitForWrt	; block until EEPROM write has finished.<BR>\
	bcf		EECON1,WREN	; disable EROM<BR>\
<BR>\
	; NOTE:- I have commented out the goto and the write to eeprom started to work<BR>\
	<BR>\
;	btfsc	EECON1,WR	<BR>\
;	goto	EEwaitForWrt<BR>\
	<BR>\
	;bcf	EECON1,EEIF	; EEPROM finished<BR>\
<BR>\
	banksel	0	<BR>\
	return<BR>\
<BR>\
;<BR>\
; EEPROM for program<BR>\
; a - setaddr<BR>\
; e - erase32 words at address.<BR>\
; < - read word and increment<BR>\
; > - write word and increment, needs to write 4 butes at once.<BR>\
;<BR>\
<BR>\
<BR>\
EEincProgAddr<BR>\
;	banksel	RSeeaddrl<BR>\
;	incfsz	RSeeaddrl<BR>\
;	goto	$+2<BR>\
;	incfsz	RSeeaddrh<BR>\
<BR>\
	banksel	EEADR<BR>\
	incfsz	EEADR<BR>\
	return<BR>\
	banksel	EEADRH<BR>\
	incf	EEADRH,f	<BR>\
	return<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sun, 5 Apr 2009 07:53:41 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"; Binary-to-BCD",
"",
"",
"",
";<BR>\
;********************************************************************<BR>\
;                  Binary To BCD Conversion Routine<BR>\
;      This routine converts a 16 Bit binary Number to a 5 Digit<BR>\
;      This routine converts a 24 Bit binary Number to an 8 Digit<BR>\
; BCD Number. This routine is useful since PIC16C55 & PIC16C57<BR>\
; have  two 8 bit ports and one 4 bit port ( total of 5 BCD digits)<BR>\
;<BR>\
;       The 16 bit binary number is input in locations H_byte and<BR>\
; L_byte with the high byte in H_byte.<BR>\
;       The 5 digit BCD number is returned in R0, R1 and R2 with R0<BR>\
; containing the MSD in its right most nibble.<BR>\
;<BR>\
;   Performance :			16 bit	24 bit<BR>\
;               Program Memory  :       35	<BR>\
;               Clock Cycles    :       885	2100 approx<BR>\
;<BR>\
; This file is based on the file BCD.ASM found on www.crownhill.co.uk<BR>\
;<BR>\
;*******************************************************************;<BR>\
;<BR>\
;<BR>\
<BR>\
B2_BCD  bcf     STATUS,0                ; clear the carry bit<BR>\
	movlw   .32	; number of bits to convert.<BR>\
	movwf   BCDcount<BR>\
	clrf    BCDop0<BR>\
	clrf    BCDop1<BR>\
	clrf    BCDop2<BR>\
	clrf    BCDop3<BR>\
	clrf    BCDop4<BR>\
<BR>\
BCDloop16<BR>\
	bcf	STATUS,C<BR>\
	btfsc	BCDip3,7<BR>\
	bsf	STATUS,C<BR>\
	rlf     BCDip0<BR>\
	rlf     BCDip1<BR>\
	rlf     BCDip2<BR>\
	rlf     BCDip3<BR>\
	<BR>\
	rlf     BCDop0<BR>\
	rlf     BCDop1<BR>\
	rlf     BCDop2<BR>\
	rlf     BCDop3<BR>\
	rlf     BCDop4<BR>\
;<BR>\
	decfsz  BCDcount<BR>\
	goto    BCDadjDEC<BR>\
	RETLW   0<BR>\
;<BR>\
BCDadjDEC  <BR>\
;	movlw   BCDop4<BR>\
;	movwf   FSR<BR>\
;	call    BCDadjBCD<BR>\
<BR>\
	movlw   BCDop0<BR>\
	movwf   FSR<BR>\
	call    BCDadjBCD<BR>\
<BR>\
	movlw   BCDop1<BR>\
	movwf   FSR<BR>\
	call    BCDadjBCD<BR>\
;<BR>\
	movlw   BCDop2<BR>\
	movwf   FSR<BR>\
	call    BCDadjBCD<BR>\
;<BR>\
	movlw   BCDop3<BR>\
	movwf   FSR<BR>\
	call    BCDadjBCD<BR>\
;<BR>\
	goto    BCDloop16<BR>\
;<BR>\
BCDadjBCD  <BR>\
	movlw   0x03<BR>\
	addwf   0,W<BR>\
	movwf   BCDtemp<BR>\
	btfsc   BCDtemp,3       ; test if result > 7<BR>\
	movwf   0<BR>\
	movlw   0x30<BR>\
	addwf   0,W<BR>\
	movwf   BCDtemp<BR>\
	btfsc   BCDtemp,7       ; test if result > 7<BR>\
	movwf   0               ; save as MSD<BR>\
	RETLW   0<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sun, 5 Apr 2009 07:56:08 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"; Binary-to-BCD 2",
"",
"",
"",
";----------------------------------------------------------------------;<BR>\
;                  Change binary nbr in bin to BCD                     ;<BR>\
;----------------------------------------------------------------------;<BR>\
binary_to_bcd                     ; by Scott Dattalo<BR>\
  clrf hundreds<BR>\
  swapf bin, W<BR>\
  addwf bin, W<BR>\
  andlw B\'00001111\'<BR>\
  skpndc<BR>\
    addlw 0x16<BR>\
  skpndc<BR>\
    addlw 0x06<BR>\
  addlw 0x06<BR>\
  skpdc<BR>\
  addlw -0x06<BR>\
  btfsc bin,4<BR>\
    addlw 0x16 - 1 + 0x6<BR>\
  skpdc<BR>\
    addlw -0x06<BR>\
  btfsc bin,5<BR>\
    addlw 0x30<BR>\
  btfsc bin, 6<BR>\
    addlw 0x60<BR>\
  btfsc bin,7<BR>\
    addlw 0x20<BR>\
  addlw 0x60<BR>\
  rlf hundreds, f<BR>\
  btfss hundreds, 0<BR>\
    addlw -0x60<BR>\
  movwf tens_and_ones<BR>\
  btfsc bin,7<BR>\
    incf hundreds, f<BR>\
  return<BR>\
<BR>\
<BR>\
<BR>\
<BR>\
displayAsDecimal<BR>\
	movlw	\' \'<BR>\
	call 	RStxChar<BR>\
<BR>\
     rrf    TEMP_MSB, f<BR>\
     btfsc STATUS, C<BR>\
     goto  dispnega<BR>\
     movlw  \"+\"<BR>\
     call   SendCHAR<BR>\
     goto   showlsb<BR>\
dispnega:<BR>\
     movlw  \"-\"<BR>\
     call   SendCHAR<BR>\
     goto   showlsb<BR>\
<BR>\
     <BR>\
     <BR>\
showlsb:<BR>\
     bcf    STATUS, C<BR>\
     rrf    TEMP_LSB, f<BR>\
     btfsc STATUS, C<BR>\
     goto   got5<BR>\
     movf   TEMP_LSB,0<BR>\
     CALL   DispDec        	; display the value      <BR>\
     movlw  \".\"<BR>\
     call   SendCHAR<BR>\
     movlw  \"0\"<BR>\
     call   SendCHAR<BR>\
;     CALL   msec250<BR>\
     GOTO   displayrest<BR>\
got5:<BR>\
     movf   TEMP_LSB,0<BR>\
     CALL   DispDec        	; display the value      <BR>\
     movlw  \".\"<BR>\
     call   SendCHAR<BR>\
     movlw  \"5\"<BR>\
     call   SendCHAR<BR>\
displayrest:<BR>\
<BR>\
    <BR>\
     movlw  \"C\"<BR>\
     call   SendCHAR<BR>\
	 return<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Mon, 6 Apr 2009 07:30:36 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"; Binary-to-BCD 3",
"",
"",
"",
"http://www.dougrice.plus.com/dev/BCDADD3.ASM"
);
gbF( // guestbook.pl 
"Doug Rice","doug.h.rice@btinternet.com","Sun, 10 May 2009 07:44:59 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"Polling 8 bits to find edges",
"",
"",
"",
"Poll() looks for an edge and sets bits in eventsUp,eventsDn,eventsAny. You treat these like the PIR in the 16FXX chips and reset the bit in your service routine. <BR>\
<BR>\
<BR>\
call poll(PORTB) <BR>\
<BR>\
#include <stdio.h> <BR>\
#include <stdlib.h> <BR>\
int IPlast = 0, <BR>\
IPnew  = 0, <BR>\
edgeUp   = 0,   edgeDn   = 0,   edgeAny   = 0, <BR>\
eventsUp = 0,  eventsDn = 0,   eventsAny = 0; <BR>\
<BR>\
<BR>\
// call using poll(PORTB) <BR>\
<BR>\
int poll( newip ){ <BR>\
<BR>\
; read PORT and apply for 8 bits at a time with this code <BR>\
; <BR>\
; For each bit <BR>\
; IPlast -------______----- <BR>\
; IPnew  ------______------ <BR>\
; <BR>\
; edgeUp ____________-_____ <BR>\
; edgeDn ______-___________ <BR>\
; edgeAny______-_____-_____ <BR>\
; <BR>\
<BR>\
; eventUp ____________----- <BR>\
; eventDn ______----------- <BR>\
; eventAny______----------- <BR>\
; <BR>\
; \"ISR\" routine has to see if any events are waiting to be serviced. <BR>\
; <BR>\
; <BR>\
IPlast = IPnew; <BR>\
IPnew = newip; <BR>\
edgeUp  = ~IPlast &  IPnew ;  <BR>\
edgeDn  =  IPlast & ~IPnew ;  <BR>\
edgeAny =  IPlast ^  IPnew ;  <BR>\
<BR>\
eventsUp  = eventsUp  | edgeUp; <BR>\
eventsDn  = eventsDn  | edgeDn; <BR>\
eventsAny = eventsAny | edgeAny; <BR>\
printf( \"  %x %x  |  %x  %x %x | %x  %x %x  \\n\", IPlast, IPnew, edgeUp, edgeDn, edgeAny, eventsUp, eventsDn, eventsAny );  <BR>\
} <BR>\
<BR>\
<BR>\
int main(int argc, char *argv[]) <BR>\
{ <BR>\
printf(\"\\n try sampling some inputs\"); <BR>\
poll(0); <BR>\
poll(0); <BR>\
poll(0); <BR>\
poll(4); <BR>\
poll(4); <BR>\
poll(5); <BR>\
poll(1); <BR>\
poll(0); <BR>\
poll(0); <BR>\
<BR>\
system(\"PAUSE\");  <BR>\
return 0; <BR>\
} <BR>\
<BR>\
/* <BR>\
Expected outputs <BR>\
try sampling some inputs <BR>\
0 0  |  0  0 0 | 0  0 0 <BR>\
0 0  |  0  0 0 | 0  0 0 <BR>\
0 0  |  0  0 0 | 0  0 0 <BR>\
0 4  |  4  0 4 | 4  0 4 <BR>\
4 4  |  0  0 0 | 4  0 4 <BR>\
4 5  |  1  0 1 | 5  0 5 <BR>\
5 1  |  0  4 4 | 5  4 5 <BR>\
1 0  |  0  1 1 | 5  5 5 <BR>\
0 0  |  0  0 0 | 5  5 5 <BR>\
0 0  |  0  0 0 | 5  5 5 <BR>\
<BR>\
Press any key to continue . . . <BR>\
*/ <BR>\
<BR>\
poll() also works for timer counters, to find edges. <BR>\
<BR>\
<BR>\
see routine pollForCondition at: <BR>\
<BR>\
http://www.dougrice.plus.com/hp/Theory/bc001_asm.txt <BR>\
<BR>\
and <BR>\
http://www.dougrice.plus.com/hp/Theory/Index.htm <BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Thu, 21 May 2009 08:32:52 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl - time",
"",
"",
"",
"#<BR>\
<BR>\
# If you are getting Interal server error messages,<BR>\
# use the code below to pipe  script errors to the browser<BR>\
use CGI::Carp ( fatalsToBrowser);<BR>\
use IO::Socket;    <BR>\
<BR>\
#&setDate();<BR>\
<BR>\
# print `notepad adsl.log`;<BR>\
<BR>\
@t = localtime();<BR>\
<BR>\
print \" $t[1] . $t[2] . $t[3] . $t[4] . \\n\";<BR>\
<BR>\
sleep( 3 );<BR>\
<BR>\
print \".. slept 10 \\n\";<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Fri, 22 May 2009 07:33:54 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl - time",
"",
"",
"",
"#<BR>\
# waittill  - waits till time on command line<BR>\
#<BR>\
# wt.pl h m<BR>\
#<BR>\
<BR>\
  $end = $ARGV[ 0 ] * 60 + $ARGV[ 1 ]; <BR>\
<BR>\
  @t = localtime();<BR>\
  $now = $t[2] * 60 + $t[1]; <BR>\
<BR>\
  print \" waiting until: \" . $end  . \" its now:\" . $ now . \"\\n\";<BR>\
<BR>\
  while ( $end > $now)  {<BR>\
    sleep( 10 );<BR>\
    @t = localtime();<BR>\
    $now = $t[2] * 60 + $t[1]; <BR>\
    print \" waiting until: \" . $ARGV[0] . \":\" . $ARGV[1]  . \" its now:\" . $t[2] . \":\" . $t[1] . \"\\n\" ;<BR>\
<BR>\
    print `dir *`;<BR>\
  }<BR>\
<BR>\
  print \".. slept 10 \\n\";<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Fri, 22 May 2009 07:40:59 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl - time",
"",
"",
"",
"#<BR>\
# waittill  - waits till time on command line<BR>\
#<BR>\
# wt.pl h m<BR>\
#<BR>\
<BR>\
  $end = $ARGV[ 0 ] * 60 + $ARGV[ 1 ]; <BR>\
<BR>\
  @t = localtime();<BR>\
  $now = $t[2] * 60 + $t[1]; <BR>\
<BR>\
  print \" waiting until: \" . $end  . \" its now:\" . $ now . \"\\n\";<BR>\
<BR>\
  while ( $end > $now)  {<BR>\
    sleep( 10 );<BR>\
    @t = localtime();<BR>\
    $now = $t[2] * 60 + $t[1]; <BR>\
    print \" waiting until: \" . $ARGV[0] . \":\" . $ARGV[1]  . \" its now:\" . $t[2] . \":\" . $t[1] . \"\\n\" ;<BR>\
<BR>\
    print `dir *`;<BR>\
<BR>\
    #!/usr/bin/perl<BR>\
<BR>\
    $pid = fork();<BR>\
    if( $pid == 0 ){<BR>\
      print \"This is child process\\n\";<BR>\
      print \"Chile process is existing\\n\";<BR>\
<BR>\
      print `dir *`;<BR>\
<BR>\
      exit 0;<BR>\
    }<BR>\
    print \"This is parent process and child ID is $pid\\n\";<BR>\
<BR>\
  }<BR>\
<BR>\
  print \".. finished\";<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sat, 23 May 2009 08:03:52 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl - start two notepads",
"",
"",
"",
"#<BR>\
#<BR>\
#<BR>\
#<BR>\
#<BR>\
#        print  `dir *`;<BR>\
<BR>\
        $pid = fork();<BR>\
<BR>\
        if( $pid == 0 ){<BR>\
	  `notepad wt2.pl`;<BR>\
          print `dir *` . \"\\n\" ;<BR>\
          print \"This is child process\\n\";<BR>\
          print \"Child process is exiting\\n\";  <BR>\
          exit 0;<BR>\
        }<BR>\
<BR>\
        $pid = fork();<BR>\
        if( $pid == 0 ){<BR>\
	  `notepad wt.pl`;<BR>\
          print \"This is child process\\n\";<BR>\
          print `cd` . \"\\n\";<BR>\
          print \"Child process is exiting\\n\";  <BR>\
          exit 0;<BR>\
        }<BR>\
<BR>\
        print \"finishing... \\n\";<BR>\
<BR>\
        exit 0;<BR>\
"
);
gbF( // guestbook.pl 
"doug","doug.h.rice@btinternet.com","Sat, 23 May 2009 08:32:32 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl - start two notepads",
"",
"",
"",
"#<BR>\
# This per script forks two notepads on PC and only ends when both children end.<BR>\
#<BR>\
#<BR>\
#<BR>\
#        print  `dir *`;<BR>\
<BR>\
        $cnt = 0;<BR>\
<BR>\
<BR>\
        $pid = fork();<BR>\
        if( $pid == 0 ){<BR>\
	  #<BR>\
	  # child<BR>\
	  # <BR>\
          <BR>\
 	  # open notepad and block<BR>\
	  `notepad wt2.pl`;<BR>\
<BR>\
	  # now print out dir<BR>\
          print `dir *` . \"\\n\" ;<BR>\
          print \"This is child process\\n\";<BR>\
          print \"Child process is exiting\\n\";  <BR>\
          exit 0;<BR>\
<BR>\
<BR>\
        } else {<BR>\
	  #<BR>\
	  # parent<BR>\
	  # <BR>\
	  while($cnt < 5){<BR>\
	    sleep(1);<BR>\
            print \"I am $cnt ...\\n\";<BR>\
            $cnt = $cnt+1<BR>\
          }<BR>\
          print \"finishing... \\n\";<BR>\
<BR>\
          $pid = fork();<BR>\
          if( $pid == 0 ){<BR>\
  	    #<BR>\
	    # child<BR>\
	    # <BR>\
 	<BR>\
 	    # open notepad and block<BR>\
  	    `notepad wt.pl`;<BR>\
            print \"This is child process\\n\";<BR>\
            print `cd` . \"\\n\";<BR>\
            print \"Child process is exiting\\n\";  <BR>\
            exit 0;<BR>\
          } else {<BR>\
	    #<BR>\
	    # parent<BR>\
	    # <BR>\
       <BR>\
  	    while($cnt < 15){<BR>\
	      sleep(1);<BR>\
              print \"I was $cnt ...\\n\";<BR>\
              $cnt = $cnt+1<BR>\
            }<BR>\
            print \"finishing... \\n\";<BR>\
            exit 0;<BR>\
          }<BR>\
          exit 0;<BR>\
        }<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Tue, 26 May 2009 22:09:24 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"perl  and bash",
"",
"",
"",
"#<BR>\
#<BR>\
#<BR>\
#<BR>\
$temp = `date +%y%m%d`;<BR>\
$cnt = 0;<BR>\
<BR>\
while( $cnt <10) {<BR>\
  printf( \"hello $temp  $cnt --  $ARGV[0] -- $ARGV[1] -- $ARGV[2] --- \\n\" );<BR>\
  $cnt ++;<BR>\
  sleep( 5 )<BR>\
}<BR>\
printf( \"end\\n\");<BR>\
#<BR>\
# usage:   bash tt.sh<BR>\
#<BR>\
#<BR>\
#<BR>\
perl tt.pl $0 $1 1 &<BR>\
perl tt.pl $0 $1 2 &<BR>\
perl tt.pl $0 $1 3 &<BR>\
perl tt.pl $0 $1 4 &<BR>\
perl tt.pl $0 $1 5 &<BR>\
perl tt.pl $0 $1 6 &<BR>\
jobs<BR>\
wait<BR>\
echo \"sh ended ... \"<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Wed, 27 May 2009 08:31:09 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"bash - date",
"",
"",
"",
"#! /var/bin/bash<BR>\
<BR>\
echo \"hello doug\"<BR>\
#<BR>\
# create new directory based on data<BR>\
#<BR>\
dstr=`date +cg015_%y%m%d`<BR>\
<BR>\
echo $dstr<BR>\
mkdir $dstr<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Mon, 22 Jun 2009 22:21:18 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"gawk - server",
"",
"",
"",
"#<BR>\
#<BR>\
# Usage: gawk -f gws.awk<BR>\
#<BR>\
#<BR>\
<BR>\
# Server<BR>\
BEGIN {<BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
<BR>\
<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  system(\"sleep 3\") <BR>\
  print strftime() |& \"/inet/tcp/8888/0/0\"<BR>\
  close( \"/inet/tcp/8888/0/0\" )<BR>\
}<BR>\
<BR>\
"
);
gbF( // guestbook.pl 
"doug","","Mon, 22 Jun 2009 22:24:11 UTC+0100","212.56.108.219  | dougrice.plus.com  ",
"gawk - client",
"",
"",
"",
"#<BR>\
#<BR>\
# Usage: gawk -f gwc.awk<BR>\
#<BR>\
#<BR>\
#client<BR>\
BEGIN {<BR>\
  NetService = \"/inet/tcp/0/localhost/8888\"<BR>\
#  \"/inet/tcp/0/localhost/8888\" |& getline <BR>\
<BR>\
#  NetService |& getline <BR>\
  <BR>\
  while( (NetService |& getline) > 0 ){<BR>\
    print $0<BR>\
  }<BR>\
  close(NetService)<BR>\
  print \"Ended...\" <BR>\
}<BR>\
"
);
