There is an even more generic way than pinning by version number:
create a new file
/etc/apt/preferences.d/fpc
Package: fpc*
Pin: release a=now
Pin-Priority: 1001
The a=now filter matches manually installed packages that were installed with dpkg and the priority >1000 ensures that it will always have higher priority than every other package source, even those with higher versions. And because we don't mention a specific version number it would stay that way and still work if you later install the next version manually and Ubuntu then releases an even higher version number too.
If you issue the command
apt-cache policy
you will see the following output:
Package files:
100 /var/lib/dpkg/status
release a=now
500 http://security.ubuntu.com/ubuntu bionic-security/multiverse i386 Packages
release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=multiverse,b=i386
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu bionic-security/universe i386 Packages
release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=universe,b=i386
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu bionic-security/main i386 Packages
release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=main,b=i386
origin security.ubuntu.com
100 http://de.archive.ubuntu.com/ubuntu bionic-backports/universe i386 Packages
release v=18.04,o=Ubuntu,a=bionic-backports,n=bionic,l=Ubuntu,c=universe,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic-updates/multiverse i386 Packages
release v=18.04,o=Ubuntu,a=bionic-updates,n=bionic,l=Ubuntu,c=multiverse,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic-updates/universe i386 Packages
release v=18.04,o=Ubuntu,a=bionic-updates,n=bionic,l=Ubuntu,c=universe,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic-updates/main i386 Packages
release v=18.04,o=Ubuntu,a=bionic-updates,n=bionic,l=Ubuntu,c=main,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic/multiverse i386 Packages
release v=18.04,o=Ubuntu,a=bionic,n=bionic,l=Ubuntu,c=multiverse,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic/universe i386 Packages
release v=18.04,o=Ubuntu,a=bionic,n=bionic,l=Ubuntu,c=universe,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic/restricted i386 Packages
release v=18.04,o=Ubuntu,a=bionic,n=bionic,l=Ubuntu,c=restricted,b=i386
origin de.archive.ubuntu.com
500 http://de.archive.ubuntu.com/ubuntu bionic/main i386 Packages
release v=18.04,o=Ubuntu,a=bionic,n=bionic,l=Ubuntu,c=main,b=i386
origin de.archive.ubuntu.com
Pinned packages:
fpc -> 3.0.4 with priority 1001
fpc-src -> 3.0.4 with priority 1001
In the last two lines you can see that it has matched my manually installed fpc-3.0.4 and fpc-src-3.0.4 and gave them priority 1001 (which means always keep this, even if higher versions from other repositories are available)
An alternative way that also works would be to match release o=Ubuntu and give it priority of -1 which means "never install", this has the effect of effectively blacklisting all fpc packages that originate from Ubuntu and also works for our purpose.
---
btw the reason it uninstalled lazarus was probably that lazarus-project depends on fpc-src and fpc-src-3.0.4 depends on fpc-3.0.4 from upstream but the Ubuntu version of fpc did not satisfy these dependencies and now fpc-src and lazarus-project had to be uninstalled automatically. I have also tried to pin lazarus-project with 1001 to enforce this dependency chain from the other end but this did not work.