Re: print correctly BCD CMOS RTC values
Posted: Mon Oct 15, 2018 8:25 am
umm if you say the 'outw' function i've just deleted it, i didn't even knew that it was there
The Place to Start for Operating System Developers
http://f.osdev.org/
Code: Select all
outportb(ADDRESS_REG, param)
I wasn't going to say this, because while this does go against convention, it really is just convention. Still, I agree that it would make sense to change it to fit that convention, both as a means of managing the files, and to avoid confusion.thomtl wrote:include/system/system.h
include/system/system.c
Also .c files should go in their own directory and not in the include folder
Code: Select all
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
uint8_t nybbles_to_bcd(uint8_t hi, uint8_t lo)
{
if (hi > 9 || lo > 9)
return 0xff; // give an out-of-bounds error code
// move the value of 'hi' to upper nybble then OR with 'lo'
return ((hi << 4) | lo);
}
uint8_t uint_to_bcd(uint8_t value)
{
uint8_t hi, lo;
if (value > 99)
{
return 0xff; // give an out-of-bounds error code
};
lo = value % 10; // the hex value of the unit decimal
hi = (value / 10); // the decimal value of the tens decimal
hi *= 16; // convert the tens decimal to hex
assert((hi >> 4) < 10);
assert(lo < 10);
return hi | lo;
}
// ucbd_to_unint - converts 1-byte unpacked BCD value to
// a 1-byte binary integer
uint8_t bcd_to_uint(uint8_t bcd)
{
uint8_t hi, lo;
hi = bcd >> 4; // shift high nybble into low nybble
lo = bcd & 0x0f; // mask off upper nybble
hi *= 10;
// alt. version to tweak performance - the compiler's optimizer
// should be smart enough to emit this code for you
// automatically anyway, but it might be worth knowing
// hi = (hi << 3) + hi + hi;
assert((hi + lo) < 100);
return hi + lo;
}
int main(void)
{
uint8_t a, a_prime, b, c, d, e;
do
{
puts("Enter a two one-digit decimal values to convert: ");
scanf("%hhu %hhu", &a, &a_prime);
b = nybbles_to_bcd(a, a_prime);
if (b == 0xff)
{
printf("either %hhu or %hhu has more than two digits, please try again\n", a, a_prime);
a = 1;
continue;
}
printf("%hhu%hhu as Packed BCD ", a, a_prime);
printf("- hex %hhx, decimal %hhu\n", b, b);
c = bcd_to_uint(b);
printf("bcd_to_uint() returns: hex %hhx, decimal %hhu\n", c, c);
puts("converting back to BCD -");
d = uint_to_bcd(c);
if (d == 0xff)
{
printf("%hhu is more than two digits, please try again\n", c);
a = 1;
continue;
}
printf("hex %hhx, decimal %hhu\n", d, d);
e = bcd_to_uint(d);
printf("bcd_to_uint() returns: hex %hhx, decimal %hhu\n", e, e);
}
while ((a + a_prime) != 0);
return 0;
}
Oh, I get that, I think, but my point is that while you might want a directory for them on the individual development hosts, you usually wouldn't want the Object Files themselves in the online hosted repo - they just take up space on the cloud host, and increase the download bandwidth for anyone else who is cloning or forking the repo.alberinfo wrote:in the repo are the .bin and .o files 'cause i want to have an apart dir to have the .o and bin files, and if you see a 'obin' directory you probably won't know what's the reason of it, so you can enter and see whats in
Code: Select all
# build-generated binaries
*.o
*.elf
*.a
*.so
*.d
*.bin
/bin
*.iso
# linker-generated data files
*.map
# various types of backup files
*.*~
%*%
*.bak
# log files and directories
/log
*.log
On the one hand, I was using that to test the code; you should be able to remove the asserts without any problems.alberinfo wrote:when i compile the code, ld gives: undefined reference to '__assert_fail'
it's a problem from the assert function, but the assert.h is included
Code: Select all
qemu-system-i386 -rtc base=2011-11-11T11:11:00 -cdrom Slidoor.iso -S -s &
gdb obin/bootloader.bin \
-ex 'target remote localhost:1234' \
-ex 'break *main' \
-ex 'layout src' \
-ex 'continue'
I don't believe the standard puts any restrictions on main's prototype when compiling for a non-hosted environment using GCC's -ffreestanding optionSchol-R-LEA wrote:On a slightly related note: don't name the entry point to your kernel main(). the main() function has a very specific use in C, with a specific set of allowable function signatures, and using the name main() for anything else tends to break a lot of things. You probably want to use a name such as kmain() or something. I'm frankly surprised it compiled at all as it is - if you were using the recommended
Code: Select all
extern int foo; // in the header file
int foo; // in the source file
Code: Select all
/* assert.h - utility macro for basic sanity-check testing
/* to use this as an example, you set up the header guards like so -
these will ensure that the header body only gets compiled
once per compilation unit */
#ifndef __ASSERT_H__
#define __ASSERT_H__
/* this is just a stub version, which assumes that there is some
abort or exit operation that it can call. A more complete version
would do things like print the failed assertion. You would have to use
whatever you implement in your OS to do this. */
#define assert(exp) if (!(exp)) exit(-1); // assumes 'exit()' exists
#endif // close assert .h body
Code: Select all
/* bcd.h - declarations for packed-BCD-related functions */
#ifndef __BCD__H__
#define __BCD__H__
typedef uint8_t bcd_t;
/* constants for the BCD functions
MAX_BCD and MIN_BCD are the largest and smallest values
representable by a one-byte packed BCD value. MAX_BCD_INPUT.
The binary representation of a packed BCD is such that the two nibbles
have the equivalent *hex* values of the digits, not the decimal values,
and the value ranges are disjoint - there are 8-bit binary values which do
not represent a BCD value at all.
MAX_BCD_INPUT is that largest binary value that can be converted to
a Packed Binary-Coded Decimal value.
ERR_BCD_OVF is an out-of-range error code for indicating that
the value being converted exceeded MAX_BCD_INPUT.
*/
#define MAX_BCD 0x99
#define MIN_BCD 0
#define MAX_BCD_INPUT 99
#define ERR_BCD_OVF 0xFF
bcd_t uint_to_bcd(uint8_t value);
uint8_t bcd_to_int(bcd_t bcd);
#endif // closing body of bcd.h
Code: Select all
/* bcd.c - functions for handling BCD values */
// make sure that stdint.h is included before bcd.h
#include <stdint.h>
#include "bcd.h"
bcd_t uint_to_bcd(uint8_t value)
{
uint8_t hi, lo;
if(value > MAX_BCD_INPUT)
{
return ERR_BCD_OVF ;
};
lo = value % 10;
hi = (value / 10);
hi *= 16;
return hi | lo;
}
uint8_t bcd_to_int(bcd_t bcd)
{
uint8_t hi, lo;
hi = bcd >> 4;
lo = bcd & 0x0F;
hi *= 10;
return hi + lo;
}
Code: Select all
/* cmos.h - declarations related to the CMOS settings
and Real-Time Clock */
#infdef __CMOS_H__
#define __CMOS_H__
#define ADDRESS_REG 0x70
#define DATA_REG 0x71
/* Values/Commands for RTC Registers */
#define SECOND 0x00 //Second 00-59
#define MINUTE 0x02 //Minute 00-59
#define HOUR 0x04 //Hour 00-23
#define DAY_OF_WEEK 0x06 //Day of Week 01-0DAY
#define DAY 0x07 //Day 00-31
#define MONTH 0x08 //Month 00-12
#define YEAR 0x09 //Year 00-99
/* function declarations */
uint8 get_RTC_val(uint8 param);
bool isupdateinprogress();
void set_RTC_val(uint8 param, uint8 setVal);
int get_rtc(void);
#endif
OK, fair point; I really don't know either way, as it has always been one of the "Here There Be Nasal Demons" parts of the standard. A lot of things are left to implementors once you are talking about code which is by definition non-portable.MichaelPetch wrote:I don't believe the standard puts any restrictions on main's prototype when compiling for a non-hosted environment using GCC's -ffreestanding optionSchol-R-LEA wrote:On a slightly related note: don't name the entry point to your kernel main(). the main() function has a very specific use in C, with a specific set of allowable function signatures, and using the name main() for anything else tends to break a lot of things. You probably want to use a name such as kmain() or something. I'm frankly surprised it compiled at all as it is - if you were using the recommended