I recently was experimenting with code protection on a PIC12F509 and noticed the program memory addresses under 0x40 were left readable. I confirmed this was normal when I looked at the datasheet.
So if a program is small and just extends to 0x39 it will be fully readable even if code protection is on.
So I decided to experiment with offsetting the start of the code to 0x40 so it would be protected with CP on.
I am using assembler with MPLAB X so to do this I changed the reset vector in the code from 0x000 to 0x040. Then I right clicked the project and selected project properties. Under PICkit3 I manually specified 0x040 as the start of program memory.
The assembler files compile fine without errors and the program begins at 0x040 when the microcontroller is read with CP off in MPLAB IPE. But the code doesn't run.
The code runs fine when the reset vector is 0x000 and the start of program memory for the PICkit3 is automatically selected at 0x000 in project properties.
Is there something I'm forgetting here? I can't figure out why the code won't run.
Here is the code there are two files the main file and delay loop subroutine:
; Reaction Timer game. *
; *
; Demonstrates use of Timer0 to time real-world events *
; *
; User must attempt to press button within 200 ms of "start" LED *
; lighting. If and only if successful, "success" LED is lit. *
; *
; Starts with both LEDs unlit. *
; 2 sec delay before lighting "start" *
; Waits up to 1 sec for button press *
; (only) on button press, lights "success" *
; 1 sec delay before repeating from start *
; *
list p=12F509
#include <p12F509.inc>
EXTERN delay10 ; W x 10 ms delay
;***** CONFIGURATION
; int reset, no code protect, no watchdog, int RC clock
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
;***** VARIABLE DEFINITIONS
UDATA
cnt_8ms res 1 ; counter: increments every 8 ms
;***** RC CALIBRATION
RCCAL CODE 0x3FF ; processor reset vector
res 1 ; holds internal RC cal value, as a movlw k
;***** RESET VECTOR *****************************************************
RESET CODE 0x040 ; effective reset vector
movwf OSCCAL ; apply internal RC factory calibration
pagesel start
goto start ; jump to main code
;***** Subroutine vectors
delay10r ; delay W x 10 ms
pagesel delay10
goto delay10
;***** MAIN PROGRAM *****************************************************
MAIN CODE
;***** Initialisation
start
; configure port
movlw b'111001' ; configure GP1 and GP2 (only) as outputs
tris GPIO
; configure timer
movlw b'11010100' ; configure Timer0:
; --0----- timer mode (T0CS = 0)
; ----0--- prescaler assigned to Timer0 (PSA = 0)
; -----100 prescale = 32 (PS = 100)
option ; -> increment every 32 us
;***** Main loop
main_loop
; turn off both LEDs
clrf GPIO
; delay 2 sec
movlw .200 ; 200 x 10 ms = 2 sec
pagesel delay10r
call delay10r
pagesel $
; indicate start
bsf GPIO,2 ; turn on start LED
; wait up to 1 sec for button press
banksel cnt_8ms ; clear timer (8 ms counter)
clrf cnt_8ms ; repeat for 1 sec:
wait1s clrf TMR0 ; clear Timer0
w_tmr0 ; repeat for 8 ms:
btfss GPIO,3 ; if button pressed (GP3 low)
goto wait1s_end ; finish delay loop immediately
movf TMR0,w
xorlw .250 ; (250 ticks x 32 us/tick = 8 ms)
btfss STATUS,Z
goto w_tmr0
incf cnt_8ms,f ; increment 8 ms counter
movlw .125 ; (125 x 8 ms = 1 sec)
xorwf cnt_8ms,w
btfss STATUS,Z
goto wait1s
wait1s_end
; indicate success if elapsed time < 200 ms
movlw .25 ; if time < 200 ms (25 x 8 ms)
subwf cnt_8ms,w
btfss STATUS,C
bsf GPIO,1 ; turn on success LED
; delay 1 sec
movlw .100 ; 100 x 10 ms = 1 sec
pagesel delay10r
call delay10r
pagesel $
; repeat forever
goto main_loop
END
And the delay subroutine:
#include <p12F509.inc>
GLOBAL delay10
;***** VARIABLE DEFINITIONS
UDATA
count res 1
count2 res 1
count3 res 1
;Subroutine
CODE
delay10
banksel count3 ; Select proper bank for variables
movwf count3 ; Move number Of 10ms loops 10ms * X from W to count3
dly movlw .252
movwf count
movlw .13
movwf count2
dly2 decfsz count,f
goto dly2
decfsz count2,f
goto dly2
decfsz count3,f
goto dly
retlw 0 ; Return from subroutine with 0 in W register
END
**** Update ****
I updated the reset vector and I believe I have it working properly.
;***** RESET VECTOR *****************************************************
RESET CODE 0x000
goto 0x040
RESET2 CODE 0x040 ; apply internal RC factory calibration
movwf OSCCAL
pagesel start
goto start ; jump to main code
Best Answer
You have placed somethiung that you call the reset vector at a different location, but the chip doesn't care: its hardware still starts executing at 0 after a reset. So to implement what you want you'd better take Krankshaft's suggestion: put a jump at 0 to the code that you want to be read-protected. Mayeb you can put a few uninteresting subroutines (like a delay) between 0 and 40.