Tutorial 14: Programming the Kernel 1
Moderator:Moderators
Yes - you should always use unsigned when communicating with hardware unless you are specifically told not to.
when you define a char to be signed, it instructs the code to treat the raw data as if it were in Two's Compliment' form.
This basically negates value of the most significant bit. Therefore for a byte, the MSB means -128.
then you just add that like the rest of the bits.
e.g.
1000000 = -128
1000001 = -127
1111111 = -1
0000000 = 0
0000001 = 1
0111111 = 127
Two's compliments gives the same range as unsigned (-128 to 127 still has a range of 256 values) but the numbers are centred (ish - not exact because of the even number of values) around 0 rather than starting at 0.
As for the error, try writing the port access code directly in ASM.
Here is an example that gets the floppy drive types from CMOS
This code returns the nibble representing the 1st floppy drive in bl and the 2nd drive in cl. The values should be as below:
Number Meaning
0 No Drive
1 360kb 5.25"
2 1.2mb 5.25"
3 720kb 3.5"
4 1.44mb 3.5"
5 2.88mb 3.5"
If you are getting the value of 16 in either of the nibbles then it may be a problem with your hardware which is rather harder to fix.
Hope this helps,
Andrew
when you define a char to be signed, it instructs the code to treat the raw data as if it were in Two's Compliment' form.
This basically negates value of the most significant bit. Therefore for a byte, the MSB means -128.
then you just add that like the rest of the bits.
e.g.
1000000 = -128
1000001 = -127
1111111 = -1
0000000 = 0
0000001 = 1
0111111 = 127
Two's compliments gives the same range as unsigned (-128 to 127 still has a range of 256 values) but the numbers are centred (ish - not exact because of the even number of values) around 0 rather than starting at 0.
As for the error, try writing the port access code directly in ASM.
Here is an example that gets the floppy drive types from CMOS
Code: Select all
mov eax,0x10
out 0x70,al
in al,0x71
mov bl,al
shr bl,4
mov cl,al
and cl,0x0F
Number Meaning
0 No Drive
1 360kb 5.25"
2 1.2mb 5.25"
3 720kb 3.5"
4 1.44mb 3.5"
5 2.88mb 3.5"
If you are getting the value of 16 in either of the nibbles then it may be a problem with your hardware which is rather harder to fix.
Hope this helps,
Andrew

Here are the new versions.
Both of these routines were tested and verified that they should work fine.
Please let me know if there is any problem with the above routines still.
I also verified the above methods with keyboard port io, and Andyhhp assembly example.
Both of these routines were tested and verified that they should work fine.
Code: Select all
// read byte from port
inline unsigned char _cdecl inportb (unsigned short portid) {
_asm {
mov dx, word ptr [portid]
in al, dx
mov byte ptr [portid], al
}
return portid;
}
// write byte to port
inline void _cdecl outportb (unsigned short portid, unsigned char value) {
_asm {
mov al, byte ptr [value]
mov dx, word ptr [portid]
out dx, al
}
}
I also verified the above methods with keyboard port io, and Andyhhp assembly example.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Thank you very much, I'll test them out in the morning when I get a chance.
About the unsigned thing. I wouldn't ever do it except I was just testing to see if I could get the inportb to work. I changed all sorts of things... char to short, short to long, signed, unsigned. Hopefully it's all fixed now. Thanks again!
About the unsigned thing. I wouldn't ever do it except I was just testing to see if I could get the inportb to work. I changed all sorts of things... char to short, short to long, signed, unsigned. Hopefully it's all fixed now. Thanks again!
Just a small question.
In your inportb function, why are you copying al back into portid before returning?
As the return value is stored in eax, surely it would be quicker and easier to do the following.
In this case, the value is automatically inserted into eax, which wont contain any ah information, and saves two memory reads.
Does this make sense?
Andrew
Code: Select all
inline unsigned char _cdecl inportb (unsigned short portid) {
_asm {
mov dx, word ptr [portid]
in al, dx
mov byte ptr [portid], al
}
return portid;
}
As the return value is stored in eax, surely it would be quicker and easier to do the following.
Code: Select all
inline unsigned char _cdecl inportb (unsigned short portid) {
_asm {
mov dx, word ptr [portid]
xor eax,eax
in al, dx
}
return;
}
Does this make sense?
Andrew
