| Quozl's 16F84 to 12C509 Porting Checklist |  | 
 
Update
2002-06-24
Gerrit Dijkstra made an adapter PCB after reading
this checklist.
Introduction
2000-07-12
How practical is it to prototype on a re-usable and quickly
reprogrammable EEPROM PIC before moving the design to a UV-erasable or
one time programmable (OTP) part?  Some have done it, and this
document is the distillation of their wisdom.  Summary: there are lots
of traps.
This is Revision G of the 16F84 to 12C509 porting checklist.  Many on the PIClist have contributed, but a record
has not been kept.  The checklist is intended to be used when moving
working code from one processor to the other, and as a guide for
things to avoid when writing code that one day may be moved.
A source template for assembly code that can be
used on both processors is included.
Legend
A keyword colour pattern is used throughout the checklist, as described in
this table:
| Colour | Meaning | 
| blue, common
 | Keywords that are portable, common to both processors. | 
| green, ok
 | Keywords that are specific to the 12C509 processor, that therefore
would need to be encased within macros or ifdef sections. | 
| red, wrong
 | Keywords that are specific to the 16F84 processor, that therefore
would need to be replaced with keywords or code re-engineered for the
12C509 processor, or again encased within macros or ifdef sections. | 
Checklist
Here is the checklist.  One method of using this is to print it out,
sit down at your favourite source code editor, bring up your project
source and move down the list ticking each item that your code passes.
Then go and re-engineer the code for what you are missing.
- include P12C509A.INC instead of
P16F84.INC in source,
 
- check __CONFIG flags,
        - use of MCLRE,
        
- no use of PWRTE,
        
- valid oscillator configuration,
	
- if not using _MCLRE_OFF,
	
	
- if using _IntRC_OSC,
	
	        - clock may drift, check any external timing assumptions,
	        
- check first instruction is MOVWF OSCCAL,
	        
- check 0x3ff is not to be programmed
		(contains MOVLW for
		OSCCAL),
	
 
- if using JW part (quartz windowed erasable), save OSCCAL from 0x3ff and program,
 
 
- instructions not available,
	- check code for no use of instructions
	SUBLW,
	ADDLW, nor
	RETFIE,
	
- check use of RETLW
	instead of RETURN, [Dwayne
	Reid]
 
 
- peripherals not available,
	- check code for no use of register addresses
	EEDATA,
	EEADR,
	PCLATH,
	INTCON,
	EECON1, nor
	EECON2,
 
 
- port and TRIS latches,
	- check code for no use of register addresses
	PORTA, 
	PORTB,
	
- substitute GPIO for
	PORTB, same address (0x06),
	
- no use of TRISA nor
	TRISB register addresses,
	
- use of TRIS instruction required,
 
 
- general register file access,
	- check register file addresses used do not exceed limits
	(valid range is 0x07 to 0x1f and 0x30 to 0x3f, addresses below
	0x0c are in use on 16F84 anyway, so this is the first common
	free address),
	
- check code for FSR register,
	
		- ensure MSB of FSR
		is not used, [Marc Hoffknecht]
		
- FSR bit 5 must be
		zero for direct access to file registers in the range
		0x00-0x1f, and must be one for 0x30-0x3f.
	
 
 
 
- special register file addresses,
	- built-in registers,
	
		- check code for no use of 
		STATUS bits
		IRP,
		RP1, nor 
		RP0,
	
 
- check code for OPTION_REG register,
	
	        - no use of OPTION_REG,
	        
- use of OPTION
	        instruction,
	        
- no use of OPTION_REG bits
		RBPU nor
		INTEDG,
		
- T0CS bit must be '0' if
		GP2 is output, [Michael
		Ghormley]
	
 
 
 
- CALL/RETLW usage
	- check stack depth does not exceed two levels, [G. Daniel]
	
- CALL can only work to
	addresses 0x000-0x0ff,
	
- CALL can only work to
	addresses 0x200-0x2ff if PA0
	set,
	
- use a vector table if entry points are outside these ranges,
 
 
- GOTO usage
	- GOTO works for
	0x000-0x1ff normally,
	
- GOTO can only work to
	addresses 0x200-0x3ff if PA0
	set,
	
- ADDWF to PCL can only work to 0x000-0x0ff,
	or 0x200-0x2ff if PA0 set.
 
The following assembly source is a suggested template for developing
portable assembly code for both processors using gpasm.  Note the use
of the ifdef directive to determine which sections are to be
processed.
| 
; define one of these if your assembler fails to define them
;__16f84	equ	1
;__12c509	equ	1
	ifdef		__16f84
	processor	16f84
	include		"p16f84.inc"
	__config	_cp_off & _wdt_on & _hs_osc
	endif
	ifdef		__12c509
	processor	12c509
	include		"p12c509a.inc"
	__config	_mclre_off & _cp_off & _wdt_on & _intrc_osc
        endif
	
	ifdef	__16f84
base	equ	0x0c		; first free file register address
port	equ     portb		; port on which bits are used
movwt	macro			; move w to tris
        tris	trisb
	endm
page0	macro
	endm
page1	macro
	endm
	endif
	ifdef	__12c509
base	equ	0x07		; first free file register address
port	equ	gpio		; port on which bits are used
movwt	macro			; move w to tris
	tris	gpio
	endm
page0	macro			; select low bank for goto/call
	bcf	status,pa0
	endm
page1	macro			; select high bank for goto/call
	bsf	status,pa0
	endm
	endif
	cblock	base
		ephemeral	; temporary storage
		...
	endc
	;; start of executable code
	
	org	0x0
	ifdef	__12c509
	movwf	OSCCAL		; calibrate internal oscillator
	endif
	page1
	goto	main		; go to main program
	...
	;; calibration for 12C509-JW part
	ifdef	__12c509
	org	0x3ff
	movlw	0x50			; my 12c509 #1
	; movlw	0x30			; my 12c509 #2
	endif
	end
 | 
| quozl@us.netrek.org
| up |