Tutorial 14: Programming the Kernel 1

Announcements, Test requests, Job openings, Updates, or just make your web site known to everyone!

Moderator:Moderators

User avatar
JonnyPop
Posts:6
Joined:Fri Jan 25, 2008 2:01 am
Location:Québec, Québec

Post by JonnyPop » Thu Feb 07, 2008 11:29 pm

you should post your 'inportb()' function too since your problem really seems to be inside that one, not in your keyboard handler.

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Thu Feb 07, 2008 11:42 pm

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

Code: Select all

mov eax,0x10
out 0x70,al
in al,0x71

mov bl,al
shr bl,4
mov cl,al
and cl,0x0F
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
Image

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Post by Mike » Fri Feb 08, 2008 12:57 am

Here are the new versions.

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
	}
}
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.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com

pathos
Moderator
Posts:97
Joined:Thu Jan 10, 2008 6:43 pm
Location:USA

Post by pathos » Fri Feb 08, 2008 1:32 am

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!

pathos
Moderator
Posts:97
Joined:Thu Jan 10, 2008 6:43 pm
Location:USA

Post by pathos » Fri Feb 08, 2008 2:44 pm

YaY! It works like a charm. Thanks, Mike!

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Sun Feb 10, 2008 3:20 am

Just a small question.

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;
} 
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.

Code: Select all

inline   unsigned char _cdecl inportb (unsigned short portid) {

   _asm {
      mov      dx, word ptr [portid]
      xor      eax,eax
      in       al, dx
   }
   return;
} 
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
Image

Post Reply