Joystick control by direct hardware access is a bit of a pain by the way. Main problem is that the ADC hardware lives in a different location on BBCs and Masters, so you'll have to take that into account, depending on the results of OSBYTE 0.
The joystick fire button is easy: this just comes from bit 4 of &FE40 (remembering to configure bits 4-7 as read bits by writing &0F to &FE42).
Reading the joystick direction is a bit more involved. You have to set off two ADC conversions, one on channel 0 (X direction) and the other on channel 1 (Y direction). If you do this in 8 bit mode, the results will arrive more quickly.
Here's how Blurp does it (I assemble &FEC0 as the address of the ADC, like a BBC B, and self-modify this to &FE18 at startup if it's running on a Master):
At initialisation time (once only):
1) turn off interrupts
2) poll bit 6 of FEC0 and wait for it to be clear (this signifies that an ADC conversion is already in process - you want to ignore the interrupt that this would generate, and as far as I know, there's no way to abort/cancel the conversion).
3) write &10 to &FE4D to clear the ADC interrupt flag
4) write &90 to &FE4E to enable ADC interrupts
In the VSync IRQ handler:
1) Poll joystick button. If pressed (bit 4 of FE40 clear), this means that a joystick is connected (force the fire button to be pressed by insisting on "Press SPACE or FIRE" to begin

Flag somewhere that a joystick is connected.
2) If a joystick is connected, write 0 to &FEC0. This sets off an ADC conversion on channel 0 with 8-bit precision. When the conversion is finished, an interrupt will be generated which you can check at the beginning of your handler.
In the ADC IRQ handler:
1) Acknowledge the ADC IRQ by reading from &FE40 and throwing away the result.
2) Load &FEC0. Bit 0 tells us if the result is from ADC channel 0 or 1.
3) If it's channel 0, then bits 4-5 tell us whether the joystick is left, centred or right:
Code:
00 = right (I think)
11 = left
01 or 10 = centred.
Then write 1 to &FEC0 to start an ADC conversion on channel 1.
4) If it's channel 1, then read bits 4-5 to tell whether the joystick is up, centred or down.
Bit of a brisk overview but hopefully you get the idea.
Incidentally, even if you're doing it OS-legally, there are some things you can do to get slightly better performance:
OSBYTE 16 with X=2 will ensure that only 1 joystick is polled
OSBYTE 190 with X=8 will do 8 bit conversion which is much quicker.