Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
*.c
harpy
*.txt
*.o
*.bin
*.img
6 changes: 3 additions & 3 deletions examples/dot_anon.cx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//# 67
struct Foo {
int x;
static Foo new() => .{30}
static int get(Foo f) => f.x
static Foo new() => .{30};
static int get(Foo f) => f.x;
}

int get(Foo f) => f.x
int get(Foo f) => f.x;

int main() {
Foo f = .new();
Expand Down
17 changes: 17 additions & 0 deletions examples/dot_anon4.cx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//# 67
struct Bar {
union foo {
int i;
}
}

struct Foo {
Bar bar;
}

int main() {
Foo f = .{
bar = .{ foo.i = 67 }
};
return f.bar.foo.i;
}
15 changes: 15 additions & 0 deletions examples/enum2.cx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Bar\n
import std.io;

enum Foo {
Baz,
Bar
}

int main() {
Foo bar = .Bar;
if bar == .Baz
printf("Equals\n");
printf("%s\n", bar.id);
return 0;
}
2 changes: 1 addition & 1 deletion examples/function_overload.cx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//# 60
int sum(int x, int y) overload => x + y
int sum(int x, int y) overload => x + y;

double sum(double x, double y) overload {
return x + y;
Expand Down
23 changes: 23 additions & 0 deletions examples/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
all: os.img

boot.bin: boot.asm
nasm -f bin boot.asm -o boot.bin

entry.o: entry.asm
nasm -f elf32 entry.asm -o entry.o

kernel.o:
cx --cflags="-m32 -ffreestanding -fno-pie -fno-pic -fno-stack-protector -c" kernel.cx -o kernel.o --gcc --no-header

kernel.bin: entry.o kernel.o
ld -m elf_i386 -T linker.ld entry.o kernel.o -o kernel.bin

os.img: boot.bin kernel.bin
cat boot.bin kernel.bin > os.img
truncate -s 1440K os.img

run: os.img
qemu-system-x86_64 -drive format=raw,file=os.img,index=0,media=disk

clean:
rm -f *.bin *.o os.img
72 changes: 72 additions & 0 deletions examples/kernel/boot.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
bits 16
org 0x7C00

start:
; Configura segmentos em Real Mode
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00

; Habilita a linha A20 (Fast A20 Gate)
in al, 0x92
or al, 2
out 0x92, al

; Carrega o kernel (setor 2 em diante)
mov ah, 0x02 ; Função de leitura
mov al, 10 ; Número de setores
mov ch, 0 ; Cilindro 0
mov cl, 2 ; Setor 2
mov dh, 0 ; Cabeça 0
mov bx, 0x1000 ; Endereço de destino
int 0x13 ; Chamada BIOS

; Entra em Modo Protegido
cli
lgdt [gdt_descriptor]

mov eax, cr0
or eax, 1
mov cr0, eax

jmp 0x08:protected_mode

bits 32
protected_mode:
; Atualiza os registradores de segmento para 32-bit (Data Segment selector 0x10)
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

; --- CORREÇÃO CRUCIAL: Aponta a pilha para uma área segura ---
mov esp, 0x90000

; Chama o ponto de entrada do kernel
call 0x1000

; Loop infinito caso o kernel retorne
cli
hlt
jmp $

gdt_start:
dq 0x0
gdt_code:
dw 0xFFFF, 0x0
db 0x0, 0x9A, 0xCF, 0x0
gdt_data:
dw 0xFFFF, 0x0
db 0x0, 0x92, 0xCF, 0x0
gdt_end:

gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start

times 510-($-$$) db 0
dw 0xAA55
10 changes: 10 additions & 0 deletions examples/kernel/entry.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bits 32
section .text
global _start_trampoline
extern _start ; Referência para a função gerada pelo CX/C

_start_trampoline:
call _start ; Pula com segurança para o kernel
cli ; Se o kernel retornar (não deveria), desabilita interrupções
hlt ; Trava a CPU
jmp $
105 changes: 105 additions & 0 deletions examples/kernel/kernel.cx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const int VGA_WIDTH = 80;
const int VGA_HEIGHT = 25;
volatile char* VIDEO_MEM = (char*) 0xB8000;

char make_color(char fg, char bg) => fg | (bg << 4);

void clear_screen(char bg_color) {
char attr = make_color(0x0F, bg_color);
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT * 2; i += 2) {
VIDEO_MEM[i] = ' ';
VIDEO_MEM[i + 1] = attr;
}
}

void put_char_at(char c, char color, int x, int y) {
int offset = (y * VGA_WIDTH + x) * 2;
VIDEO_MEM[offset] = c;
VIDEO_MEM[offset + 1] = color;
}

void print_at(const char* msg, char color, int x, int y) {
int i = 0;
while msg[i] != '\0' {
put_char_at(msg[i], color, x + i, y);
i++;
}
}

void draw_box(char color) {
// Linhas horizontais (topo e base)
for (int x = 0; x < VGA_WIDTH; x++) {
put_char_at('-', color, x, 0);
put_char_at('-', color, x, VGA_HEIGHT - 1);
}
// Linhas verticais (lados)
for (int y = 0; y < VGA_HEIGHT; y++) {
put_char_at('|', color, 0, y);
put_char_at('|', color, VGA_WIDTH - 1, y);
}
// Cantos
put_char_at('+', color, 0, 0);
put_char_at('+', color, VGA_WIDTH - 1, 0);
put_char_at('+', color, 0, VGA_HEIGHT - 1);
put_char_at('+', color, VGA_WIDTH - 1, VGA_HEIGHT - 1);
}

void print_int_at(int num, char color, int x, int y) {
for (int c = 0; c < 8; c++)
put_char_at(' ', color, x + c, y);

char[12] buf;
int idx = 0;

if num == 0 {
put_char_at('0', color, x, y);
return;
}

// Extrai os dígitos do fim para o começo
while num > 0 {
buf[idx++] = '0' + (num % 10);
num = num / 10;
}

// Imprime invertido para sair na ordem certa
for (int i = 0; i < idx; i++)
put_char_at(buf[idx - 1 - i], color, x + i, y);
}

int _start() {
// 0x00 = Preto, 0x01 = Azul, 0x02 = Verde, 0x04 = Vermelho, 0x0E = Amarelo, 0x0F = Branco
char theme_bg = 0x01; // Fundo Azul
clear_screen(theme_bg);

// UI Básica
char border_color = make_color(0x0E, theme_bg); // Texto Amarelo no Fundo Azul
draw_box(border_color);

char title_color = make_color(0x0F, theme_bg); // Texto Branco no Fundo Azul
print_at("=== CX OPERATING SYSTEM v0.1 ===", title_color, 24, 2);

char text_color = make_color(0x0A, theme_bg); // Texto Verde Claro
print_at("[OK] Protected Mode active (32-bit)", text_color, 4, 5);
print_at("[OK] VGA Memory mapped to 0xB8000", text_color, 4, 6);
print_at("[OK] CX Driver initialized successfully!", text_color, 4, 7);

// Status Bar / Ticks no Rodapé
char status_color = make_color(0x00, 0x07); // Texto Preto no Fundo Cinza
for (int x = 1; x < VGA_WIDTH - 1; x++)
put_char_at(' ', status_color, x, VGA_HEIGHT - 2);

print_at("Kernel Status: RUNNING", status_color, 3, VGA_HEIGHT - 2);

// Infinite Loop com Contador de Ciclos
int ticks = 0;
while true {
ticks++;
print_at("Cycles: ", status_color, 55, VGA_HEIGHT - 2);
print_int_at(ticks, status_color, 63, VGA_HEIGHT - 2);
// Pequeno atraso visual para não atualizar rápido demais
for (int delay = 0; delay < 1000000; delay++) __raw { asm("nop"); }
}

return 0;
}
29 changes: 29 additions & 0 deletions examples/kernel/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ENTRY(_start_trampoline)
OUTPUT_FORMAT("binary")

SECTIONS
{
/* Diz ao linker que o bootloader carrega tudo em 0x1000 */
. = 0x1000;

.text : ALIGN(4) {
/* Garante que o trampolim seja literalmente o primeiro byte */
entry.o(.text)
*(.text)
*(.text.*)
}

.rodata : ALIGN(4) {
*(.rodata)
*(.rodata.*)
}

.data : ALIGN(4) {
*(.data)
}

.bss : ALIGN(4) {
*(COMMON)
*(.bss)
}
}
2 changes: 1 addition & 1 deletion examples/map.cx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct Fun<T, U> {
}
}

float toFloat(int x) => (float) x * 1.5F
float toFloat(int x) => (float) x * 1.5F;

int main() {
int[5] nums = [1, 2, 3, 4, 5];
Expand Down
2 changes: 1 addition & 1 deletion examples/raw1.cx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ u32 fast_add(u32 a, u32 b) {
return result;
}

u32 count_leading_zeros(u32 x) => __builtin_clz(x)
u32 count_leading_zeros(u32 x) => __builtin_clz(x);

int main() {
printf("fast_add: %u\n", fast_add(10, 20));
Expand Down
21 changes: 6 additions & 15 deletions examples/vm/vm2.cx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ enum OpCode {
Halt,
}

char* opCodeToStr(OpCode op)
{
if op == OpCode.Push return "Push";
if op == OpCode.Add return "Add";
if op == OpCode.Print return "Print";
if op == OpCode.Halt return "Halt";
return "Invalid OpCode";
}

struct Instruction {
OpCode op;
VMValue value;
Expand All @@ -36,19 +27,19 @@ struct VMValue {
long i;
float f;
};
static VMValue mkInt(long i) => (VMValue) {VMType.Int, value.i = i}
static VMValue mkFloat(float i) => (VMValue) {VMType.Float, value.f = i}
static VMValue mkInt(long i) => (VMValue) {VMType.Int, value.i = i};
static VMValue mkFloat(float i) => (VMValue) {VMType.Float, value.f = i};
}

alias SValue = VMValue!StackError

struct VM
struct VM
{
Array<Instruction> program;
Stack<VMValue> stack;
u32 offset;

static VM new(Array<Instruction> program) => (VM) { program, Stack<VMValue>.new(8), 0 }
static VM new(Array<Instruction> program) => (VM) { program, Stack<VMValue>.new(8), 0 };

void run() {
while self.offset < self.program.size
Expand Down Expand Up @@ -90,10 +81,10 @@ struct VM
printf("%lld\n", v.value.i);
else
printf("%f\n", v.value.f);
return;
continue;

default:
printf("Invalid opcode '%s'.\n", opCodeToStr(instr.op));
printf("Invalid opcode '%s'.\n", instr.op.id);
continue;
}
}
Expand Down
Loading
Loading