home | terminal | snapshot | hardware | microcode engine | operating system | c compiler & assembler | c library | resources | photos & videos | system overview | interrupts & dma | instruction set | system verilog model | kernel overview | file system | system calls | shell | programs & games | how to build a program | github | youtube | contact

C programs are written almost exaclty as you would in Linux, except for the system calls and C library.
printf() is not yet implemented, so print strings with prints().
Most standard C functions are not yet implemented, but a few are. You can find all the implemented ones
inside stdio.h.


Example program:

#include 

int main(){
  // you can declare local variables as normal
  int i;

  print("Print strings with print() as printf() is under construction.\n");
  print("Print numbers with printu() for unsigned and prints() for signed.\n");

  for(i = 0; i < 100; i++){
    printu(i);
    print("\n");
  } 

  return 0;
}



To build this program and run:
 1. cd into the 'sol-1/ccompiler' directory.
 2. ./build test.c

This will compile your C program, assemble it, generate a hexadecimal block of code and copy it to your clipboard.

 3. head into sol-1.org via telnet on port 51515.
 4. cd /tmp
 5. mkbin myfirstprogram

Then press shift+insert, or ctrl+shift+v, in order to paste the hexadecimal code block. Wait about 30 seconds for the transfer to complete
and then press return.

 6. run the program with ./myfirstprogram



This is the current implementation of stdio.h. Note all functions are implemented in code here. #include #define NULL 0 struct va_list{ char *p; // pointer to current argument }; struct FILE { int fd; // file descriptor for the open file unsigned char *buf;// pointer to buffer for I/O operations unsigned int bufsize; // size of buffer unsigned int bufpos; // position of next character in buffer int mode; // file mode (read, write, append, etc.) int error; // error flag }; inline int va_arg(struct va_list *arg, int size){ int val; if(size == 1){ val = *(char*)arg->p; } else if(size == 2){ val = *(int*)arg->p; } else{ print("Unknown type size in va_arg() call. Size needs to be either 1 or 2."); } arg->p = arg->p + size; return val; } void printf(char *format, ...){ char *p; char *fp; int i; fp = format; p = &format; for(;;){ if(!*fp) break; if(*fp == '%'){ fp++; switch(*fp){ case 'd': case 'i': p = p - 2; prints(*(int*)p); break; case 'u': p = p - 2; printu(*(unsigned int*)p); break; case 'x': p = p - 2; printx16(*(unsigned int*)p); break; case 'c': p = p - 2; putchar(*(char*)p); break; case 's': p = p - 2; print(*(char**)p); break; default: print("Error: Unknown argument type.\n"); } fp++; } else { putchar(*fp); fp++; } } } void printx16(int hex) { asm{ meta mov d, hex mov b, [d] call print_u16x } } void printx8(char hex) { asm{ meta mov d, hex mov bl, [d] call print_u8x } } int hex_to_int(char *hex_string) { int value = 0; int i; char hex_char; int len; len = strlen(hex_string); for (i = 0; i < len; i++) { hex_char = hex_string[i]; if (hex_char >= 'a' && hex_char <= 'f') value = (value * 16) + (hex_char - 'a' + 10); else if (hex_char >= 'A' && hex_char <= 'F') value = (value * 16) + (hex_char - 'A' + 10); else value = (value * 16) + (hex_char - '0'); } return value; } int atoi(char *str) { int result = 0; // Initialize result int sign = 1; // Initialize sign as positive // Skip leading whitespaces while (*str == ' ') str++; // Check for optional sign if (*str == '-' || *str == '+') { if (*str == '-') sign = -1; str++; } // Loop through all digits of input string while (*str >= '0' && *str <= '9') { result = result * 10 + (*str - '0'); str++; } return sign * result; } int gets(char *s){ asm{ meta mov d, s mov a, [d] mov d, a call _gets } return strlen(s); } void prints(int num) { char digits[5]; int i = 0; if (num < 0) { putchar('-'); num = -num; } else if (num == 0) { putchar('0'); return; } while (num > 0) { digits[i] = '0' + (num % 10); num = num / 10; i++; } while (i > 0) { i--; putchar(digits[i]); } } void printu(unsigned int num) { char digits[5]; int i; i = 0; if(num == 0){ putchar('0'); return; } while (num > 0) { digits[i] = '0' + (num % 10); num = num / 10; i++; } // Print the digits in reverse order using putchar() while (i > 0) { i--; putchar(digits[i]); } } char rand(){ char sec; asm{ mov al, 0 syscall sys_rtc ; get seconds mov al, ah meta mov d, sec mov al, [d] } return sec; } void date(){ asm{ mov al, 0 ; print datetime syscall sys_datetime } } void putchar(char c){ asm{ meta mov d, c mov al, [d] mov ah, al call _putchar } } char getchar(){ char c; asm{ call getch mov al, ah meta mov d, c mov [d], al } return c; } int scann(){ int m; asm{ call scan_u16d meta mov d, m mov [d], a } return m; } void puts(char *s){ asm{ meta mov d, s mov a, [d] mov d, a call _puts mov a, $0A00 syscall sys_io } } void print(char *s){ asm{ meta mov d, s mov d, [d] call _puts } } int loadfile(char *filename, char *destination){ asm{ meta mov d, destination mov a, [d] mov di, a meta mov d, filename mov d, [d] mov al, 20 syscall sys_filesystem } } int create_file(char *filename, char *content){ } int delete_file(char *filename){ asm{ meta mov d, filename mov al, 10 syscall sys_filesystem } } struct FILE *fopen(char *filename, char *mode){ } void fclose(struct FILE *fp){ } // heap and heap_top are defined internally by the compiler // so that 'heap' is the last variable in memory and therefore can grow upwards // towards the stack char *alloc(int bytes){ heap_top = heap_top + bytes; return heap_top - bytes; } char *free(int bytes){ return heap_top = heap_top - bytes; } void exit(){ asm{ syscall sys_terminate_proc } } void load_hex(char *destination){ char *temp; temp = alloc(32768); asm{ ; ************************************************************ ; GET HEX FILE ; di = destination address ; return length in bytes in C ; ************************************************************ _load_hex: push a push b push d push si push di sub sp, $8000 ; string data block mov c, 0 mov a, sp inc a mov d, a ; start of string data block call _gets ; get program string mov si, a __load_hex_loop: lodsb ; load from [SI] to AL cmp al, 0 ; check if ASCII 0 jz __load_hex_ret mov bh, al lodsb mov bl, al call _atoi ; convert ASCII byte in B to int (to AL) stosb ; store AL to [DI] inc c jmp __load_hex_loop __load_hex_ret: add sp, $8000 pop di pop si pop d pop b pop a } } unsigned char getparam(char *address){ char data; asm{ mov al, 4 meta mov d, address mov d, [d] syscall sys_system meta mov d, data mov [d], bl } return data; } void clear(){ print("\033[2J\033[H"); } void include_stdio_asm(){ asm{ .include "lib/stdio.asm" } }


Paulo Constantino - CC BY-NC-SA 4.0 DEED Attribution-NonCommercial-ShareAlike 4.0 International