Tutorial 14: Programming the Kernel 1

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

Moderator: Moderators

Postby 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.
User avatar
JonnyPop
 
Posts: 6
Joined: Fri Jan 25, 2008 2:01 am
Location: Québec, Québec

Postby 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
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby 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
User avatar
Mike
Site Admin
 
Posts: 463
Joined: Sat Oct 20, 2007 7:58 pm

Postby 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

Postby pathos » Fri Feb 08, 2008 2:44 pm

YaY! It works like a charm. Thanks, Mike!
pathos
Moderator
 
Posts: 97
Joined: Thu Jan 10, 2008 6:43 pm
Location: USA

Postby 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
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Previous

Return to Your Announcements

Who is online

Users browsing this forum: No registered users and 2 guests

cron