If you do erase this, it can be restored using POKECODE. Assuming you have found the best value, say $2D, you can use POKECODE @$3FF, $2D to replace it.

This produces;

org 3FFh
retlw 2Dh

Then when you use DEFINE OSCCAL_1K 1, this inserts a call to the last program code location, lands on the retlw (return with literal in the W reg), which, in this case, would be 2Dh. On return, W reg is moved in the into the OSCCAL reg for you.

If you use DEFINE OSCCAL_1K 1, and this location has been erased, it just wraps around from 3FFh back to square 1, and you have a continuous loop because there is no longer a retlw 2Dh instruction there.

The best way I have found to get the factory OSCCAL value is to setup OSC2 to output Fosc/4 and watch this pin with a scope. When you hit the magic number, you'll see 1MHz output on OSC2.

Then use POKECODE to store this value in the last program memory location, and you're good to go.

If you don't have access to a scope, you can setup a loop sending each new OSCCAL value to a serial terminal program. When you get close, you'll start seeing values on-screen. When it's way out of tune, you'll see garbage characters, or nothing.

Normally you'll have 15 to 20 values show up. I take the one in the center, and use that for my OSCCAL value to be restored with POKECODE.