Volvemos de nuevo con el mismo problema de siempre.... LOS NÚMEROS DENTRO DEL ORDENADOR SE TRATAN COMO NÚMEROS EN FORMATO BINARIO, no tienes un entero en formato decimal ni uno en formato hexadecimal, octal, o lo que sea, los números se tratan en binario. Los transistores del uprocesador tienen limitaciones y entre ellas están que sólo saben operar con 1s y 0s. Espero que esto quede claro de una vez.
La función Outportb() recibirá dos valores que serán tipo int, float, char (en tu caso como dices tipo char).... Esto es lo único que te tiene que interesar, pues si a la función antes mencionada le pasas el valor 31 como decías:
outportb(3f8,0x1f);
es igual a hacer lo siguiente:
outportb(3f8,31);
Al fin y al cabo a la función outportb le llegará el siguiente valor: 0001 1111, se lo pases en decimal o en hexadecimal. El compilador de C te permite trabajar con números en decimal: a= 31, como en hexadecimal (si añades al principio el 0x): a=0x1f. Pero esto sólo es una ayuda para el programador, para que pueda escribir su código bien usando notación decimal como hexadecimal, para hacer el código más sencillo para el programador, pero por dentro esos valores son números binarios y al programa le da exactamente igual que se los hayas pasado en hexadecimal o en decimal.
Tu programa se puede escribir de varias formas por tanto:
int valor;
valor=0x1f; //se le pasa un valor en hexadecimal, aunque en valor se guardará 0001 1111
outportb(3f8,(char)valor);
valor=31;//en forma decimal, en valor se vuelve a guardar lo mismo de antes 0001 1111
outportb(3f8,(char)valor);//se hace exactamente lo mismo que antes
outportb(3f8,31);//hace lo mismo
outportb(3f8,0x1f);//de nuevo se hace lo mismo que antes
Como conclusión, da igual con qué tipo de números trabajes cuando escribes un código (decimal o hexadecimal) porque a la hora de la verdad el programa trabajará con los números en formato binario, y por tanto da igual que a una función le pases el número en uno u otro formato, siempre lo recibirá en binario.
Deja de darle vueltas al decimal y al hexadecimal.
Una última cosa, en el programa estás trabajando con una variable tipo int que ocupa 32bits, y la función outportb() recibe una variable de tipo char de 8 bits(según dices), así que ten cuidado con el valor que introduces pues tiene que estar en el rango de 0 a 255, de esta manera podrás hacer el cast sin problemas de pérdida de datos.
Un saludo