Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Time Command #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/time/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
##
# Makefile for calc.
#
CC=gcc
CFLAGS=-m32 -Os -mpush-args -fno-pie -fomit-frame-pointer -fno-builtin -nostartfiles -nostdlib -nodefaultlibs
AS=as
LD=ld
OUTPUT=time

OBJECTS=crt0.o syscalls.o printf.o stdlib.o time.o

all: $(OBJECTS)
$(LD) $(OBJECTS) -melf_i386 -Ttext=C0000C --oformat=binary -o $(OUTPUT)
#$(LD) $(OBJECTS) -melf_i386 -o $(OUTPUT)

%.o: %.c
$(CC) $(CFLAGS) -c $<

%.o: %.s
$(AS) --32 $< -o $@

clean:
@rm $(OBJECTS) || true
@[ -f $(OUTPUT) ] && rm $(OUTPUT) || true

9 changes: 9 additions & 0 deletions apps/time/crt0.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.global _start,main

.text
_start:
call main

loop:
jmp loop

18 changes: 18 additions & 0 deletions apps/time/minilibc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

#ifndef _MINILIBC
#define _MINILIBC

#include "stdarg.h"

#define CHECK_BIT(a, b) ((a >> b) & 0x01)
#define SET_BIT(a, b) a |= (0x01 << b)

long write(int fd, void *buf, unsigned long count);
long read(int fd, void *buf, unsigned long count);
int vsprintf(char *str, const char *format, va_list ap);
int sprintf(char *str, const char *format, ...);
int _printf(const char *format, ...);
int atoi(const char *nptr);

#endif

326 changes: 326 additions & 0 deletions apps/time/printf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
/*
* Copyright (C) 2009 Renê de Souza Pinto
* Tempos - Tempos is an Educational and multi purpose Operating System
*
* File: printf.c
* Desc: Implements the printf family C functions
*
* This file is part of TempOS.
*
* TempOS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* TempOS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "minilibc.h"

#define MAXDIG 20

#define FLAG_ALT 0x00
#define FLAG_ZPAD 0x01
#define FLAG_FB 0x02
#define FLAG_SPACE 0x03
#define FLAG_PLUS 0x04

/** Signed conversion */
#define SIGNED 1
/** Unsigned conversion */
#define UNSIGNED 0

#define MAX_PRINTF_SIZE 1024

static void numtostr(char **dest, char flags, long int value, int base, int prec, char sig);


/**
* Convert number to string (in specific base)
* \param dest Destination of converted string
* \param flags Flags
* \param value Numeric value
* \param base The base (2 = binary / 10 = decimal / 16 = hexa)
* \param prec Precision
* \param sig Signed conversion (0 = unsigned)
*/
static void numtostr(char **dest, char flags, long int value, int base, int prec, char sig)
{
char *ndest = *dest;
long int pos, div, quo;
unsigned long int udiv, uquo, rem;
char temp, sch, fch;
int i, sh, len;

/* This is painful, there is a better way? */
pos = 0;
if(sig) {
/* Signed conversion */
div = value < 0 ? (value * -1) : value; /* Dividend (absolute) */
quo = 1; /* Quotient */
rem = 0; /* Remainder */
if(base != 16) {
while(quo != 0) {
quo = (div / base);
rem = (div % base);
div = quo;
ndest[pos] = (rem + '0');
pos++;
}
} else {
while(quo != 0) {
quo = (div / base);
rem = (div % base);
div = quo;
if(rem >= 10) {
ndest[pos] = (rem - 10 + 'A');
} else {
ndest[pos] = (rem + '0');
}
pos++;
}
}
} else {
/* Unsigned conversion */
udiv = (unsigned)value; /* Dividend (absolute) */
uquo = 1; /* Quotient */
rem = 0; /* Remainder */
if(base != 16) {
while(uquo != 0) {
uquo = (udiv / base);
rem = (udiv % base);
udiv = uquo;
ndest[pos] = (rem + '0');
pos++;
}
} else {
while(uquo != 0) {
uquo = (udiv / base);
rem = (udiv % base);
udiv = uquo;
if(rem >= 10) {
ndest[pos] = (rem - 10 + 'A');
} else {
ndest[pos] = (rem + '0');
}
pos++;
}
}
}
pos--;
for(i=0; i<=(pos / 2); i++) {
temp = ndest[i];
ndest[i] = ndest[pos-i];
ndest[pos-i] = temp;
}

/* Signal */
sh = 0;
sch = 0;
if( CHECK_BIT(flags, FLAG_SPACE) || CHECK_BIT(flags, FLAG_PLUS) ) {
sh = 1;
if(value >= 0) {
if( CHECK_BIT(flags, FLAG_PLUS) ) {
sch = '+';
} else {
sch = ' ';
}
} else {
if(sig)
sch = '-';
}
}

/* Shift */
fch = ' ';
pos++;
if(prec > 0) {
len = (prec - pos);
if(len > 0)
sh += len;

if( CHECK_BIT(flags, FLAG_ZPAD) )
fch = '0';
}
if(sh > 0) {
for(i=pos; i>=0; i--)
ndest[i + sh] = ndest[i];

for(i=0; i<sh; i++)
ndest[i] = fch;

if( sch ) {
if( CHECK_BIT(flags, FLAG_ZPAD) )
ndest[0] = sch;
else
ndest[sh - 1] = sch;
}
}

*dest += (pos + sh);
}


/**
* Formatted output conversion
* \param str Destination string
* \param format Format
* \param ap Variable arguments list
*/
int vsprintf(char *str, const char *format, va_list ap)
{
char *fmt = (char *)format;
char *nstr = str;
char flags = 0;
char num[MAXDIG], *src;
int p;

while(*fmt) {
if(*fmt != '%') {
*nstr++ = *fmt++;
} else {
/* conversion specification */
while(*fmt++) {
/* Flags */
rflags:
switch(*fmt) {
case '#':
SET_BIT(flags, FLAG_ALT);
fmt++;
goto rflags;

case '0':
SET_BIT(flags, FLAG_ZPAD);
fmt++;
goto rflags;

case '-':
SET_BIT(flags, FLAG_FB);
fmt++;
goto rflags;

case ' ':
SET_BIT(flags, FLAG_SPACE);
fmt++;
goto rflags;

case '+':
SET_BIT(flags, FLAG_PLUS);
fmt++;
goto rflags;
}

/* Field width */
p = 0;
while(*fmt && (*fmt >= '0' && *fmt <= '9'))
num[p++] = *fmt++;
num[p] = '\0';

/* Precision */
if(*fmt == '.') {
fmt++;
while(*fmt && (*fmt >= '0' && *fmt <= '9'))
num[p++] = *fmt++;
num[p] = '\0';
}

/* Length modifier */
switch(*fmt) {
case 'l':
fmt++;
break;
}

/* Modifier */
switch(*fmt) {
case 'i':
case 'd':
numtostr(&nstr, flags, (int)(va_arg(ap, int)), 10, atoi(num), SIGNED);
fmt++;
break;

case 'u':
numtostr(&nstr, flags, (unsigned int)(va_arg(ap, unsigned int)), 10, atoi(num), UNSIGNED);
fmt++;
break;

case 'o':
numtostr(&nstr, flags, (int)(va_arg(ap, int)), 8, atoi(num), SIGNED);
fmt++;
break;

case 'x':
numtostr(&nstr, flags, (int)(va_arg(ap, int)), 16, atoi(num), SIGNED);
fmt++;
break;

case 'c':
*nstr++ = (int)(va_arg(ap, int));
fmt++;
break;

case 's':
src = (char*)(va_arg(ap, char*));
while(*src)
*nstr++ = *src++;
fmt++;
break;

}
break;
}
}
}
*nstr = '\0';

return(nstr - str);
}


/**
* Formatted output conversion
* \param str Destination string
* \param format Format
* \param ...
*/
int sprintf(char *str, const char *format, ...)
{
va_list args;
int res;

va_start(args, format);
res = vsprintf(str, format, args);
va_end(args);
return(res);
}


/**
* Write formated messages.
*/
int _printf(const char *format, ...)
{
va_list args;
int i, res;
char str[MAX_PRINTF_SIZE];

va_start(args, format);
res = vsprintf(str, format, args);
va_end(args);

i = 0;
while (str[i] != '\0' && i < res) {
write(1, &str[i], 1);
i++;
}

return(i);
}

12 changes: 12 additions & 0 deletions apps/time/stdarg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _STDARG_H
#define _STDARG_H

typedef __builtin_va_list va_list;

#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define __va_copy(d,s) __builtin_va_copy(d,s)

#endif

Loading