IMHO, "code const unsigned char sintable[0x100]" does not help you at all (but it is more appropriate C style for segment CODE) if you have "wrong intention of using the sintable[]". The problem is not in this line as long as you would try to do for example "something = sintable[0x01];" only. Your problem is, that in your code is line like "sintable[0x01] = something;".
You CAN NOT modify the 2k code mem (onchip rom) by a software itself. This is the basic rule for '51 architecture (it is not Intel x86 or so called Neumann architecture in general. (Sorry, if I am wrong with its name, but I am not an expert in the CPU theory.)
So, if you would like to create the lookup table, you need to forget to modify any sintable[] member, and you can only to read out its values. Whole sintable[] have to be initialized in the code as:
code const char sintable [0x100] = {
/* 256 values for initialisation of an array: 0x00, ... */
} // sintable[]
P.S.:
Of course, somebody could point out some '51 chips (Cygnals for example) which allows you to modify "code segment" by the software itself, but I would treat them as an exception to the general rule about character of code segment, because to be able to modify code inside these microprocessors requires some extra programming and it is "advanced technique".