How can you get a random number on GBDK? - c

I'm new to C and to GBDK and I want to code a random number generator that decides between 0 and 1.
Like a 'hacker' simulator.
I have tried a lot of examples from the Internet. But none worked.
Screenshot from the output of the last attempt I made: https://i.ibb.co/f8G39vX/bgberrors.png
Last attempt code:
#include <gb/gb.h>
#include <stdio.h>
#include <rand.h>
void init();
void main()
{
init();
while(1)
{
UINT8 r = ((UINT8)rand()) % (UINT8)4;
printf(r);
}
}
void init()
{
DISPLAY_ON;
}
How can I accomplish it?

#include <gb/gb.h>
#include <stdint.h>
#include <stdio.h>
#include <rand.h>
void init();
void main()
{
init();
printf(" \n\n\n\n\n\n\n\n PRESS START!\n");
// abuse user input for seed generation
waitpad(J_START);
uint16_t seed = LY_REG;
seed |= (uint16_t)DIV_REG << 8;
initrand(seed);
while(1)
{
UINT8 r = ((UINT8)rand()) % (UINT8)2;
printf("%d", r);
}
}
void init()
{
DISPLAY_ON;
}
Tested with GBDK-2020 4.0.3
Also check the "rand" example in GBDK-2020.
Regarding the comments:
Yes, GBDK has it's own lib (including stdlib). It's probably a fork of SDCC's lib 20 years ago. Current SDCC has rand() in stdlib.h, but GBDK-2020 doesn't. Max is 0xFF, I don't know of a define for that.
Float should be avoided as much as possible, it's completely done in software, there is no hardware support for this. Double isn't really supported by the compiler and falls back to float.
There are no man pages, documentation is available here: https://gbdk-2020.github.io/gbdk-2020/docs/api/rand_8h.html or read the gbdk_manual.pdf comming with gbdk-2020

Related

Using the gotoxy() function to center X coordinate

I want to write something using printf while also centering the x coordinate and y=0.
How can I center the x coordinate? For example someone might have their compiler window open in fullscreen and others might not? I want the text in the middle. Right now x is assigned a random value (50)
#include <stdio.h>
#include <conio.h>
int main()
{
gotoxy(50,0);
printf("Test");
return 0;
}
I'm just using an online compiler right now. onlinegdb.com Was thinking if there was a way to center the x so that it's the same in every compiler.
What is possible or not isn't determined by the compiler you are using, but by the platform and the ammount of code you are prepared to write.
Standard C has no idea of consoles, windows and other platform dependent stuff. If you want to get to know something about your consoles properties you have to ask the console/operating system. There are also libraries like ncurses for POSIX that allowes different terminals POSIX systems can run on to be treated uniformly.
An implementation of the ncurses-library that is available for DOS, OS/2, Win32, X11 and SDL is PDCurses. It can be used to write platform agnostic code.
But since you mentioned that your platform is windows, here is a solution that uses only the WinAPI:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
COORD get_console_dimensions(void)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
COORD dimensions = { csbi.srWindow.Right - csbi.srWindow.Left,
csbi.srWindow.Bottom - csbi.srWindow.Top };
return dimensions;
}
COORD get_console_cursor_pos(void)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
return csbi.dwCursorPosition;
}
void gotoxy(short x, short y)
{
COORD pos = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void puts_centered(char const *str)
{
size_t length = strlen(str);
short x = (short)(get_console_dimensions().X - length) / 2;
gotoxy(x, get_console_cursor_pos().Y);
puts(str);
}
int main(void)
{
puts_centered("Hello, World!");
}
Using ncurses the same can be achieved (also works with PDCurses, include <curses.h> instead of <ncurses.h>):
#include <string.h>
#include <ncurses.h>
int main(void)
{
initscr();
int max_x = getmaxx(stdscr);
int y, x;
getyx(stdscr, y, x);
char const *str = "Hello, World!\n";
mvaddstr(y, (max_x - strlen(str)) / 2, str);
refresh();
// endwin(); // *)
}
Live: https://onlinegdb.com/HkIpXBUim
Please note that OnlineGDBs support for ncurses with its "terminal" is broken. getyx() won't tell the real width of its console.
*) Documentation says you should call endwin() before exiting your program. If you do so with OnlineGDB you won't get any visible output at all from OnlineGDB. Only if you click the "Copy output to clipboard"-button and view the copied text you'll see the ANSI escape sequences produced by ncurses.

Working example Intel RdRand in C language. How to generate a float type number in the range -100.001 through +100.001

There is an Intel DRNG Library that allows you to use a random number generator based on the processor's crystal entropy effect.
The library itself and an instruction of its use: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-library-implementation-and-uses
There is an example inside a library that just prints the contents of a randomly generated array.
Please, share the working example in C, which allows using this library to generate a float type number in the range -100.001 through +100.001
I was able to find only a code, based on the pseudo-random number generator, but it is not what I need:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
float randoms(float min, float max)
{
return (float)(rand())/RAND_MAX*(max - min) + min;
}
int main()
{
srand((unsigned int)time(0));
printf("%f\n",randoms(-100.001, 100.001));
return 0;
}
Thanks in advance.
The answer have been posted on the Intel's DRNG page not long ago. I would like to cite it here:
You can almost use that same algorithm. You just need a way to check
for the (highly unlikely) chance the RDRAND instruction will not
return a value.
Here's how I would modify your code snippet for Linux (you'll need to
supply the -mrdrnd option to gcc to compile this):
#include <stdio.h>
#include <limits.h>
char randoms(float *randf, float min, float max)
{
int retries= 10;
unsigned long long rand64;
while(retries--) {
if ( __builtin_ia32_rdrand64_step(&rand64) ) {
*randf= (float)rand64/ULONG_MAX*(max - min) + min;
return 1;
}
}
return 0;
}
int main()
{
float randf;
if ( randoms(&randf, -100.001, 100.001) ) printf("%f\n", randf);
else printf("Failed to get a random value\n");
return 0;
}
See section 4.2.1 in the above document:
4.2.1 Retry Recommendations
It is recommended that applications attempt 10 retries in a tight loop
in the unlikely event that the RDRAND instruction does not return a
random number. This number is based on a binomial probability
argument: given the design margins of the DRNG, the odds of ten
failures in a row are astronomically small and would in fact be an
indication of a larger CPU issue.

Is it possible to make a loading animation in a Console Application using C?

I would like to know if it is possible to make a loading animation in a Console Application that would always appear in the same line, like a flashing dot or a more complex ASCII animation.
Perhaps like this
#include <stdio.h>
#include <time.h>
#define INTERVAL (0.1 * CLOCKS_PER_SEC) // tenth second
int main(void) {
int i = 0;
clock_t target;
char spin[] = "\\|/-"; // '\' needs escape seq
printf(" ");
while(1) {
printf("\b%c", spin[i]);
fflush(stdout);
i = (i + 1) % 4;
target = clock() + (clock_t)INTERVAL;
while (clock() < target);
}
return 0;
}
The more portable way would be to use termcap/terminfo or (n)curses.
If you send ANSI escape sequences you assume the terminal to be capable of interpreting them (and if it isn't it'll result in a big mess.)
It's essentially a system that describes the capabilities of the terminal (if there's one connected at all).
In these days one tends to forget but the original tty didn't have a way to remove ink from the paper it typed the output on ...
Termcap tutorials are easy enough to find on Google. Just one in the GNU flavor here: https://www.gnu.org/software/termutils/manual/termcap-1.3/html_mono/termcap.html (old, but should still be good)
(n)curses is a library that will allow you control and build entire text based user interfaces if you want to.
Yes it is.
One line
At first if you want to make animation only at one line, you could use putchar('\b') to remove last character and putchar('\r') to return to line beginning and then rewrite it.
Example:
#include
#include
int main() {
int num;
while (1) {
for (num = 1; num <= 3; num++) {
putchar('.');
fflush(stdout);
sleep(1);
}
printf("\r \r"); // or printf("\b\b\b");
}
return 0;
}
But if you want to place it at specified line, you can clear and re-draw every frame, or use libs.
Clearing method
You can do this with system("clear") or with printf("\e[1;1H\e[2J").
After that you'll need to re-draw your frame. I don't recommend this method.
But this is really unportable.
Other libraries
You can use ncurses.h or conio.h depending on system type.
Ncurses example:
#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>
int main() {
int row, col;
initscr();
getmaxyx(stdscr, row, col);
char loading[] = "-\\|/";
while (1) {
for (int i = 0; i < 8; i++) {
mvaddch(row/2, col/2, loading[i%4]);
refresh();
sleep(1);
mvaddch(row/2, col/2, '\b');
}
}
endwin();
return 0;
}

Time measuring in C and linux

I want to see how much is taken by the C program, so I wrote:
#include<stdio.h>
#include<stdlib.h>
#include"memory.h"
#include"memory_debug.h"
#include<sys/times.h>
#include<unistd.h>
int (*deallocate_ptr)(memContainer *,void*);
void (*merge_ptr)(node *);
void* (*allocate_ptr)(memContainer *,unsigned long size);
memContainer* (*init_ptr)(unsigned long );
diagStruct* (*diagnose_ptr)(memContainer *);
void (*finalize_ptr)(memContainer *);
void (*printNode_ptr)(node *n);
void (*printContainer_ptr)(memContainer *c);
void info(memContainer *c)
{
struct tms *t;
t=malloc(sizeof(struct tms));
times(t);
printf("user : %d\nsystem : %d\n %d",t->tms_utime,(int)t->tms_stime);
diagnose_ptr(c);
printf("\n");
return ;
}
but when I invoke this function I get 0 user time and 0 system time, even if I write:
for (i=0;i<100000;++i)
for (j=0;j<10;++j)
{}
info(c);
what am I doing wrong?
The compiler probably optimizes away your for loops since they do nothing. Try incrementing a volatile variable.
If you only want to know the time, try running time ./app and it will print the cputime, wall clock time etc of the executed app.
The code could simply write a volatile variable at the start, put your 'work' in a function (in a separate file), then read the volatile after the 'work' and print something involving the volatile.
Or do some simple calculation with a part of the calculation buried in a function, or using a function return.
What platform (Operating system & Compiler) are you using?
I don't know what platform you are running on, but there are a few useful questions on stackoverflow about higher precision system clocks. High precision timing in userspace in Linux has several useful links and references.
Timing Methods in C++ Under Linux looked useful.
The below demo program outputs nonzero times:
#include<stdio.h>
#include<stdlib.h>
#include"memory.h"
#include<sys/times.h>
#include<unistd.h>
#include <iostream>
using namespace std;
int main()
{
int x = 0;
for (int i = 0; i < 1 << 30; i++)
x++;
struct tms t;
times(&t);
cout << t.tms_utime << endl;
cout << t.tms_stime << endl;
return x;
}
Output:
275
1

Run-time mocking in C?

This has been pending for a long time in my list now. In brief - I need to run mocked_dummy() in the place of dummy() ON RUN-TIME, without modifying factorial(). I do not care on the entry point of the software. I can add up any number of additional functions (but cannot modify code within /*---- do not modify ----*/).
Why do I need this?
To do unit tests of some legacy C modules. I know there are a lot of tools available around, but if run-time mocking is possible I can change my UT approach (add reusable components) make my life easier :).
Platform / Environment?
Linux, ARM, gcc.
Approach that I'm trying with?
I know GDB uses trap/illegal instructions for adding up breakpoints (gdb internals).
Make the code self modifiable.
Replace dummy() code segment with illegal instruction, and return as immediate next instruction.
Control transfers to trap handler.
Trap handler is a reusable function that reads from a unix domain socket.
Address of mocked_dummy() function is passed (read from map file).
Mock function executes.
There are problems going ahead from here. I also found the approach is tedious and requires good amount of coding, some in assembly too.
I also found, under gcc each function call can be hooked / instrumented, but again not very useful since the the function is intended to be mocked will anyway get executed.
Is there any other approach that I could use?
#include <stdio.h>
#include <stdlib.h>
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummy(void)
{
printf("__%s__()\n",__func__);
}
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
int main(int argc, char * argv[])
{
int (*fp)(int) = atoi(argv[1]);
printf("fp = %x\n",fp);
printf("factorial of 5 is = %d\n",fp(5));
printf("factorial of 5 is = %d\n",factorial(5));
return 1;
}
test-dept is a relatively recent C unit testing framework that allows you to do runtime stubbing of functions. I found it very easy to use - here's an example from their docs:
void test_stringify_cannot_malloc_returns_sane_result() {
replace_function(&malloc, &always_failing_malloc);
char *h = stringify('h');
assert_string_equals("cannot_stringify", h);
}
Although the downloads section is a little out of date, it seems fairly actively developed - the author fixed an issue I had very promptly. You can get the latest version (which I've been using without issues) with:
svn checkout http://test-dept.googlecode.com/svn/trunk/ test-dept-read-only
the version there was last updated in Oct 2011.
However, since the stubbing is achieved using assembler, it may need some effort to get it to support ARM.
This is a question I've been trying to answer myself. I also have the requirement that I want the mocking method/tools to be done in the same language as my application. Unfortunately this cannot be done in C in a portable way, so I've resorted to what you might call a trampoline or detour. This falls under the "Make the code self modifiable." approach you mentioned above. This is were we change the actually bytes of a function at runtime to jump to our mock function.
#include <stdio.h>
#include <stdlib.h>
// Additional headers
#include <stdint.h> // for uint32_t
#include <sys/mman.h> // for mprotect
#include <errno.h> // for errno
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummy(void)
{
printf("__%s__()\n",__func__);
}
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
typedef void (*dummy_fun)(void);
void set_run_mock()
{
dummy_fun run_ptr, mock_ptr;
uint32_t off;
unsigned char * ptr, * pg;
run_ptr = dummy;
mock_ptr = mocked_dummy;
if (run_ptr > mock_ptr) {
off = run_ptr - mock_ptr;
off = -off - 5;
}
else {
off = mock_ptr - run_ptr - 5;
}
ptr = (unsigned char *)run_ptr;
pg = (unsigned char *)(ptr - ((size_t)ptr % 4096));
if (mprotect(pg, 5, PROT_READ | PROT_WRITE | PROT_EXEC)) {
perror("Couldn't mprotect");
exit(errno);
}
ptr[0] = 0xE9; //x86 JMP rel32
ptr[1] = off & 0x000000FF;
ptr[2] = (off & 0x0000FF00) >> 8;
ptr[3] = (off & 0x00FF0000) >> 16;
ptr[4] = (off & 0xFF000000) >> 24;
}
int main(int argc, char * argv[])
{
// Run for realz
factorial(5);
// Set jmp
set_run_mock();
// Run the mock dummy
factorial(5);
return 0;
}
Portability explanation...
mprotect() - This changes the memory page access permissions so that we can actually write to memory that holds the function code. This isn't very portable, and in a WINAPI env, you may need to use VirtualProtect() instead.
The memory parameter for mprotect is aligned to the previous 4k page, this also can change from system to system, 4k is appropriate for vanilla linux kernel.
The method that we use to jmp to the mock function is to actually put down our own opcodes, this is probably the biggest issue with portability because the opcode I've used will only work on a little endian x86 (most desktops). So this would need to be updated for each arch you plan to run on (which could be semi-easy to deal with in CPP macros.)
The function itself has to be at least five bytes. The is usually the case because every function normally has at least 5 bytes in its prologue and epilogue.
Potential Improvements...
The set_mock_run() call could easily be setup to accept parameters for reuse. Also, you could save the five overwritten bytes from the original function to restore later in the code if you desire.
I'm unable to test, but I've read that in ARM... you'd do similar but you can jump to an address (not an offset) with the branch opcode... which for an unconditional branch you'd have the first bytes be 0xEA and the next 3 bytes are the address.
Chenz
An approach that I have used in the past that has worked well is the following.
For each C module, publish an 'interface' that other modules can use. These interfaces are structs that contain function pointers.
struct Module1
{
int (*getTemperature)(void);
int (*setKp)(int Kp);
}
During initialization, each module initializes these function pointers with its implementation functions.
When you write the module tests, you can dynamically changes these function pointers to its mock implementations and after testing, restore the original implementation.
Example:
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummyFn(void)
{
printf("__%s__()\n",__func__);
}
static void (*dummy)(void) = dummyFn;
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
int main(int argc, char * argv[])
{
void (*oldDummy) = dummy;
/* with the original dummy function */
printf("factorial of 5 is = %d\n",factorial(5));
/* with the mocked dummy */
oldDummy = dummy; /* save the old dummy */
dummy = mocked_dummy; /* put in the mocked dummy */
printf("factorial of 5 is = %d\n",factorial(5));
dummy = oldDummy; /* restore the old dummy */
return 1;
}
You can replace every function by the use of LD_PRELOAD. You have to create a shared library, which gets loaded by LD_PRELOAD. This is a standard function used to turn programs without support for SOCKS into SOCKS aware programs. Here is a tutorial which explains it.

Resources