In order of complexity
NIC (I haven't a clue)
Parallel is pretty nice, because in effect it becomes a shared byte between the PC and your card. The PC can write a byte to the parallel port, and your card can read that byte directly out of its version of the parallel port.
This should give you all you need to interface your own card to the parallel port of a PC
> I'm working with WinXP at the moment however eventually I'll be using Linux as well
So long as you write your own
Then you can use those throughout your code. When it's time to port to Linux, then you have only a small amount of work to do - just reimplement those for the new OS.
void parallel_write_byte ( unsigned char );
unsigned char parallel_read_byte( void );
Same goes for any other code which is Operating system specific.