PAGE0_BASE_ADDRESS is an integer value; the subexpression
(__IO uint16_t*)PAGE0_BASE_ADDRESS) expands to
(volatile uint16_t*)PAGE0_BASE_ADDRESS), which casts the integer to a volatile pointer to 16-bit unsigned integer.
Finally, the outermost asterisk is used to deference this pointer. Overall, the statement reads a 16-bit integer from the given address, considering it as a pointer to volatile memory1, meaning that it must be read/written from memory each time it is accessed (i.e. the compiler should not cache it in a register or assume that its value remains the same each time the given code is executed).
1 Not the same as a volatile pointer to normal memory (i.e.
uint16_t * volatile)