cmos hex/bcd probs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
slacker

cmos hex/bcd probs

Post by slacker »

im trying to read the time through cmos but for some reason im always reading hex numbers and when i put those through my PrintInt function the dec will be printed out. i thought BCD mode was default so i should be getting numbers (0-60) when im trying to retreieve for example, seconds. anything i dont know about cmos and numbers?

i tried making a setmode (BCD, hex) function but i get the same number no matter what.

Code: Select all

//binary or BCD
void CMOS_SetMode(bool binary)
{
unsigned char dataIn;
if(binary)
{
                Port_Out(CommandP, StatRegB);
   dataIn=Port_In(DataP);
   dataIn=dataIn|0x04;
   Port_Out(CommandP, StatRegB);
   Port_Out(DataP, dataIn);
}
else
{
   Port_Out(CommandP, StatRegB);
   dataIn=Port_In(DataP);
   dataIn=dataIn&0xFB;
   Port_Out(CommandP, StatRegB);
   Port_Out(DataP, dataIn);
}
}
When i do:
PrintInt(200); it works and prints 200 so i dont think my printint function is bad.
Therx

Re:cmos hex/bcd probs

Post by Therx »

When in binary mode the RTC should give normal number but as default it is in BCD which gives the number so that when you print it as a hex number it looks right

e.g.
BCD : Returns 21 when it is 15

I have also tried to enable binary mode but it didn't make a difference so I just wrote a routine to convert it.

Code: Select all

int convertBCD(int in)
{
   int tempno1, tempno2;
   tempno1 = trunc(in / 16);
   tempno2 = in - 16 * tempno1;
   return 10 * tempno1 + tempno2;
}
I think that was it.

Pete


P.S. Does anyone know what the point of this is because the numbers which in hex contain letters are never used (ie 15 - F)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:cmos hex/bcd probs

Post by Pype.Clicker »

as BCD stores one decimal digit per nybble, you can have it displayed correctly if you display it as an hex number:

35 (decimal) is encoded as 00100011 in binary and 00110101 in BCD.
you'll notice that 00110101 is 0x35 thus if you use %x formatting on your BCD-encoded data, you'll have it displayed correctly.

the alternative of computing val=10*(bcd/16)+(bcd%16) is valid too, but as the %d formatting will require val/10 and val%10 etc. to produce the exact display, this sounds a bit like a waste of CPU time, don't you think ?
Therx

Re:cmos hex/bcd probs

Post by Therx »

Yeh but I'd say that it is a waste of time to read the time from the rtc every timer interupt so I convert the values to decimal and then it requires a lot less code to advance them every Time Update Interrupt (from RTC)
slacker

Re:cmos hex/bcd probs

Post by slacker »

when i read from floppy drive info register (0x10) i get the 1.44 mb drive for floppyb. i do not get a reading for floppya. i didnt know you could connect two floppy drives to a x86 and why am i getting the 1.44mb drive for floppyb. which is floppya on a x86?

floppya=highbits
flobbyb=lowbits
bkilgore

Re:cmos hex/bcd probs

Post by bkilgore »

Yes, floppya is in the high nibble, and floppyb in the low one. Here's how i get the information:

Code: Select all

/* read the value from the CMOS containing 
        information about the floppy drives */
    int f = CMOS_READ(CMOS_FLOPPY_TYPES);

    /* split it into the two floppy drives */
    int floppy0 = (f >> 4) & 0xF;
    int floppy1 = f & 0xF;
slacker

Re:cmos hex/bcd probs

Post by slacker »

for floppy0 why did you '&' it? moving bits to the left will leave you will the number(0-4)
Schol-R-LEA

Re:cmos hex/bcd probs

Post by Schol-R-LEA »

bkilgore wrote: Yes, floppya is in the high nibble, and floppyb in the low one. Here's how i get the information:

Code: Select all

/* read the value from the CMOS containing 
        information about the floppy drives */
    int f = CMOS_READ(CMOS_FLOPPY_TYPES);

    /* split it into the two floppy drives */
    int floppy0 = (f >> 4) & 0xF;
    int floppy1 = f & 0xF;
While bitfields are often more hassle to use than they are worth, IMHO this would be one of the cases they would come in handy:

Code: Select all

typedef unsigned char BYTE;
typedef struct {BYTE f0:4, f1:4} FLOPPIES;
or something along those lines. I would use unsigned char rather than int because you are otherwise wasting the 3 high bytes of the int.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:cmos hex/bcd probs

Post by Pype.Clicker »

one thing, at least: if you're going to use shifts, make sure you use *unsigned* types rather than signed (int, short, long, etc) ones, while iirc, the result of right-shifting a signed value (i.e. whether the new bits are zeroes or a copy of the most significant bit) may depend on the architecture you're working on.
Post Reply