Using the expression
result = -(x & mask) + (x & !mask)
where mask=2^(n-1) yields the result you want. The (x & mask) isolates the sign bit and (x & !mask) is the offset. When the sign bit is not set, (x & mask) == 0 and (x & !mask) is the result. When the sign bit is set, -(x & mask) == -2^(n-1) and (x & !mask) is the offset from the most negative number.
Next we convert the hexadecimal string to a raw representation by using HEXTORAW(). The raw representation is cast to an integer with UTL_RAW.CAST_TO_BINARY_INTEGER().
Assuming 16 bit:
select x, -BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32768) +BITAND(utl_raw.cast_to_binary_integer(hextoraw(x)),32767) from (select '8508' x from dual);
Note: You probably want to do the utl_raw.cast_to_binary_integer(hextoraw(...)) once instead of twice.