1. You say you are programming 0x8000. But your code clearly uses 0xC000 as a destination address.
2. Programming 0x8000 with driver code at 0x4000 will succeed only for PPAGE settings <=0x3B. This is because pages 0x3C to 0x3F form single flash bank. 0x4000 belongs to PPAGE==0x3E. And code can't run in the same flash bank that is being programmed. Your code needs to execute from different flash bank, from EEPROM, from RAM or from external memory.
3. Programming 0xC000 with driver at 0x4000 also will fail. Because 0xC000 is PPAGE==0x3F. 0x4000 is PPAGE=0x3E. Both pages belong to the same flash bank.
4. Again, this your piece of code is WRONG:
FSTAT|=(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
^^ this code clears ACCERR, PVIOL bits and most likely writes "1' also to CBEIF, trying to launch flash command. Since FCMD is probably not loaded at this point, some error (PVIOL I think) will be triggered again. Please remove red symbol. I wrote already why bitfields are wrong. You do the same what compiler does for FSTAT_ACCERR=1 and FSTAT_PVIOL=1;. I'm afraid my explanation doesn't help you to understand why it's wrong.
5. This is also not right piece of code:
FSTAT |= FSTAT_CBEIF_MASK;
^^ here you are not only launching flash command, but also clearing ACCERR and PVIOL.
6. Don't forget to set up BKSEL bits in FCNFG register. 00 for pages 3C to 3F, 01 for 38-3B etc.
After fixing these issues code should start working. Of course with restrictions specified in 2 and 3, unless you move your code to RAM.