Implemented hk_printf and made everything else implicit.

Ahmmm. Also made 64 bit kernel independent(you can call that thing to enter 64 bit kernel as long as you are in protected mode (no setup required.))(not working but will soon work).
This commit is contained in:
HyperAssembler 2015-02-07 04:10:50 -08:00
parent 8e8d089578
commit 57b0f4a8f1
10 changed files with 391 additions and 178 deletions

View File

@ -1,16 +1,84 @@
extern hk_main
[SECTION .entry]
[BITS 32] ;on stack: multiboot_info*
; no, no interrupt please.
cli
global HLT_CPU
global BOCHS_MAGIC_BREAKPOINT
;IMPORTANT: Before entering this, CPU should be in protected mode.
;IMPORTANT: This module should be 4k-page aliened
[SECTION .entry]
[BITS 32]
;on stack: multiboot_info*
;skip data definition
jmp start
; here we need to construct a dummy gdt as well as a dummy page table(As simple as possible, maps 1G page sounds good)
; for page table we only need 4 gigs since that's the maximum mem one can access in protected mode(without PAE)
; flags are hard-coded... highly not recommended but for our purpose it's enough
; little-endian assumed
times (4096 - 5) db 0; skip the first jmp as well as making it kernel stack, 16 bytes aliened :D
KERNEL_STACK:
PML4_BASE:
times 512 dq 0 ;reserved the rest for page entries
PDPT_BASE:
times 512 dq 0 ;reserved the rest for page entries
GDT64: ; Global Descriptor Table (64-bit).
.NULL: equ $ - GDT64 ; The null descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 0 ; Access.
db 0 ; Granularity.
db 0 ; Base (high).
.CODE: equ $ - GDT64 ; The code descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10011000b ; Access.
db 00100000b ; Granularity.
db 0 ; Base (high).
.DATA: equ $ - GDT64 ; The data descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10010000b ; Access.
db 00000000b ; Granularity.
db 0 ; Base (high).
.GDT64_PTR: ; The GDT-pointer.
dw $ - GDT64 - 1 ; Limit.
dq GDT64 ; Base.
start:
cli
; disable paging first
mov eax, cr0 ; Set the A-register to control register 0.
and eax, 01111111111111111111111111111111b ; Clear the PG-bit, which is bit 31.
mov cr0, eax ; Set control register 0 to the A-register.
ret
xchg bx,bx ; pure magic
;pure magic
xchg bx,bx
; write values for pml4
mov eax,PML4_BASE
mov dword [eax], PDPT_BASE + 3
; write values for pdpt
xor ecx, ecx
add ecx, 131
mov eax, PDPT_BASE
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
; enable PAE
mov eax, cr4 ; Set the A-register to control register 4.
@ -24,34 +92,37 @@ or eax, 1 << 8 ; Set the LM-bit which is the 9th bit (bit 8).
wrmsr ; Write to the model-specific register.
; let cr3 point at page table
mov eax,0;page table addr
mov eax, PML4_BASE
mov cr3,eax
; enable paging, enter compatibility mode
mov eax, cr0 ; Set the A-register to control register 0.
or eax, 1 << 31 ; Set the PG-bit, which is bit 31.
mov cr0, eax ; Set control register 0 to the A-register.
ret
; enter x64
;lgdt [g_gdt_ptr_64]
jmp 8:entry_64
;lgdt [GDT64.GDT64_PTR]
jmp GDT64.CODE:entry
[SECTION .text]
[BITS 64]
entry_64:
entry:
cli
;hard code for now
mov ax,24
mov ax,GDT64.DATA
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
;well align 16 bytes like this for now
mov rax,rsp
and rax,0xFFFFFFFFFFFFFFF0
mov rsp,rax
;no params for now
; align 16 bytes like this for now
mov rsp,KERNEL_STACK
call hk_main
hlt
hlt
HLT_CPU:
hlt
BOCHS_MAGIC_BREAKPOINT:
xchg bx,bx
ret

View File

@ -3,12 +3,14 @@
#include "print.h"
#include "mem.h"
#include "multiboot.h"
#include "../../../x86/src/c/print.h"
extern uint64_t text_pos;
extern void HLT_CPU(void);
extern void BOCHS_MAGIC_BREAKPOINT();
void HYPKERNEL64 hk_main(void)
{
hk_clear_screen();
hk_print_str("Welcome to HYP OS. Kernel is now running in x64 mode.\n");
x64:
goto x64;
hk_printf("Welcome to HYP OS. Kernel is now running in x64 mode.\n");
HLT_CPU();
}

View File

@ -83,48 +83,44 @@ void HYPKERNEL64 hk_write_segment_descriptor(void * const gdt, uint32_t const ba
return;
}
void HYPKERNEL64 hk_map_page(void * const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr, uint64_t const availableRam)
uint64_t HYPKERNEL64 hk_map_page(void * const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr, uint64_t const availableRam)
{
//wait a sec, we actually need maximum memory information here for effectively map crap
if(base == NULL || p_addr << 52 || v_addr << 52)
return;
//ASSUME: little endian
//All of the following should be 4K-aliened
void * const pml4_base = base;
void * const pdpt_base = (void*)((uint64_t)((uint64_t*)pml4_base + PML4_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
void * const pd_base = (void*)((uint64_t)((uint64_t*)pdpt_base + PDPT_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
void * const pt_base = (void*)((uint64_t)((uint64_t*)pd_base + PD_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
uint64_t const pml4_index = (v_addr >> 39) & 0x1FF;
uint64_t const pdpt_index = (v_addr >> 30) & 0x1FF;
uint64_t const pd_index = (v_addr >> 21) & 0x1FF;
uint64_t const pt_index = (v_addr >> 12) & 0x1FF;
void * const pml4_entry_addr = (void*)((uint64_t*) pml4_base + pml4_index);
if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
{
//PML4 does not exist
hk_write_pml4_entry(pml4_entry_addr, (uint64_t)((uint64_t*)pdpt_base + pml4_index * 512), PML4_PRESENT | PML4_WRITE);
}
uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
{
hk_write_pdpt_entry(pdpt_entry_addr, (uint64_t)((uint64_t*)pd_base + pml4_index * 512 * 512 + pdpt_index * 512), PDPT_PRESENT | PDPT_WRITE);
}
uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
{
hk_write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
}
uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
hk_write_pt_entry(pt_entry_addr, p_addr, attr);
return;
//
// void * const pml4_entry_addr = (void*)((uint64_t*) base + pml4_index);
// if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
// {
// //PML4 does not exist
// hk_write_pml4_entry(pml4_entry_addr, (uint64_t)((uint64_t*)pdpt_base + pml4_index * 512), PML4_PRESENT | PML4_WRITE);
// }
// uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
//
// void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
// if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
// {
// hk_write_pdpt_entry(pdpt_entry_addr, (uint64_t)((uint64_t*)pd_base + pml4_index * 512 * 512 + pdpt_index * 512), PDPT_PRESENT | PDPT_WRITE);
// }
// uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
//
// void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
// if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
// {
// hk_write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
// }
// uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
//
// void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
// hk_write_pt_entry(pt_entry_addr, p_addr, attr);
return 0;
}
void HYPKERNEL64 hk_mem_cpy(void* src, void* dst, uint64_t size)

View File

@ -1,3 +1,4 @@
#include <stdarg.h>
#include "kdef.h"
#include "type.h"
#include "mem.h"
@ -7,7 +8,7 @@ uint64_t text_pos;
uint64_t HYPKERNEL64 hk_str_len(char const * str)
{
uint32_t length = 0;
uint64_t length = 0;
if(str == NULL)
return 0;
while(*str != 0)
@ -22,7 +23,7 @@ uint64_t HYPKERNEL64 hk_str_cmp(char const * str1,char const * str2)
{
if(str1 == NULL || str2 == NULL)
return 0;
uint32_t length = hk_str_len(str1);
uint64_t length = hk_str_len(str1);
if(length != hk_str_len(str2))
return 0;
while(length--)
@ -39,7 +40,7 @@ void HYPKERNEL64 hk_print_scroll()
return;
}
void HYPKERNEL64 hk_print_str(char const *str)
void HYPKERNEL64 _print_str(char const *str)
{
if(str == NULL)
return;
@ -74,7 +75,26 @@ void HYPKERNEL64 hk_print_str(char const *str)
return;
}
void HYPKERNEL64 hk_print_int(int64_t number)
void HYPKERNEL64 _print_uint(uint64_t number)
{
char arr[21]; // do not need to initialize
arr[20] = 0; //zero-terminated
uint32_t index = 19;
uint32_t const div = 10;
while (1)
{
uint64_t quo = number / div;
uint64_t rmd = number % div;
number = quo;
arr[index--] = (char) ('0' + rmd);
if (number == 0)
break;
}
_print_str(&(arr[index + 1]));
return;
}
void HYPKERNEL64 _print_int(int64_t number)
{
char arr[21]; // do not need to initialize
arr[20] = 0; //zero-terminated
@ -91,24 +111,23 @@ void HYPKERNEL64 hk_print_int(int64_t number)
int64_t quo = number / div;
int64_t rmd = number % div;
number = quo;
arr[index] = (char) ('0' + rmd);
index--;
arr[index--] = (char) ('0' + rmd);
if (number == 0)
break;
}
if (isNegative)
{
arr[index] = '-';
hk_print_str(&(arr[index]));
arr[index--] = '-';
}
else
hk_print_str(&(arr[index+1]));
_print_str(&(arr[index + 1]));
return;
}
void HYPKERNEL64 hk_print_hex(uint64_t number)
void HYPKERNEL64 _print_hex(uint64_t number, uint64_t capital)
{
const char lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
char const * const look_up = capital == 1 ? lookup_table_cap : lookup_table;
char arr[19];
arr[18] = 0; //zero-terminated
uint32_t index = 17;
@ -118,13 +137,13 @@ void HYPKERNEL64 hk_print_hex(uint64_t number)
uint64_t quo = number / div;
uint64_t rmd = number % div;
number = quo;
arr[index--] = lookup_table[rmd];
arr[index--] = look_up[rmd];
if (number == 0)
break;
}
arr[index--] = 'x';
arr[index] = '0';
hk_print_str(&(arr[index]));
_print_str(&(arr[index]));
return;
}
@ -134,3 +153,61 @@ void HYPKERNEL64 hk_clear_screen(void)
hk_mem_set((void*)0xb8000, 0, 25*80*2);
return;
}
void HYPKERNEL64 hk_printf(char const *format, ...)
{
va_list args;
va_start(args, format);
char buf[2] = {0, 0};
int32_t d;
uint32_t u;
char* s;
char c;
for(;*format != '\0';format++)
{
if (*format != '%')
{
buf[0] = *format;
_print_str(buf);
continue;
}
format++;
switch (*format)
{
case 'd':
d = va_arg(args, int64_t);
_print_int(d);
break;
case 'u':
u = va_arg(args, uint64_t);
_print_uint(u);
break;
case 's':
s = va_arg(args, char *);
_print_str(s);
break;
case 'c':
c = va_arg(args, int64_t);
buf[0] = c;
_print_str(buf);
break;
case 'x':
u = va_arg(args, uint64_t);
_print_hex(u, 0);
break;
case 'X':
u = va_arg(args, uint64_t);
_print_hex(u, 1);
break;
case '%':
buf[0] = '%';
_print_str(buf);
break;
default:
buf[0] = '%';
_print_str(buf);
format--;
break;
}
}
}

View File

@ -7,11 +7,9 @@
#define get_row(pos) (pos / 80)
#define get_pos(row,col) ((row) * 80 + (col))
void HYPKERNEL64 hk_print_hex(uint64_t number);
void HYPKERNEL64 hk_print_int(int64_t number);
void HYPKERNEL64 hk_print_str(char const *str);
void HYPKERNEL64 hk_clear_screen(void);
uint64_t HYPKERNEL64 hk_str_len(char const * str);
uint64_t HYPKERNEL64 hk_str_cmp(char const * str1,char const * str2);
void HYPKERNEL64 hk_printf(char const *format, ...);
#endif

View File

@ -1,13 +1,12 @@
global kernel_stack
global kernel_addr
global hk_entry_comp
global BOCHS_MAGIC_BREAKPOINT
global HLT_CPU
global hk_init_x64
extern hk_main
extern hk_print_str
extern hk_print_hex
extern hk_print_int
extern hk_printf
extern hk_enable_paging
extern hk_disable_paging
extern g_gdt_ptr_64
[SECTION .entry]
[BITS 32]
@ -45,4 +44,25 @@ popfd
push ebx
call hk_main
add esp,4 ; We are actually not coming back here. But out of courtesy...
add esp,4 ; We are actually not coming back here. But out of courtesy...
hlt
BOCHS_MAGIC_BREAKPOINT:
xchg bx,bx
ret
HLT_CPU:
hlt
;multiboot_info on stack
hk_init_x64:
push ebp
mov ebp,esp
cli
xchg bx,bx
mov edi,[ss:ebp+8] ;System V ABI
jmp 0x100000 ;hard-coded
mov esp,ebp
pop ebp
ret

View File

@ -9,11 +9,13 @@ uint8_t g_idt[8 * 256];
idt_ptr_t g_idt_ptr;
extern uint32_t text_pos;
extern void hk_entry_comp(void);
extern void hk_init_x64(multiboot_info_t* multiboot_info);
extern void BOCHS_MAGIC_BREAKPOINT(void);
extern void HLT_CPU(void);
void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
void HYPKERNEL32 hk_init_x86(multiboot_info_t * multiboot_info)
{
hk_print_str("*Setting up GDT...");
hk_printf("*Setting up GDT...");
//dummy descriptor
hk_write_segment_descriptor((void*)(&g_gdt[0]), 0, 0, 0);
//ring 0 code seg, non-conforming
@ -27,25 +29,19 @@ void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
g_gdt_ptr.limit = 8 * 8 - 1;
g_gdt_ptr.base = (uint32_t) g_gdt;
hk_load_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(3, 0));
hk_print_str(" - Done.\n\n");
hk_printf(" - Done.\n\n");
//check memory, definitely < 32 so we assume that
hk_print_str("*Checking memory information...\n");
hk_printf("*Checking memory information...\n");
if(multiboot_info->flags & (1 << 6))
{
multiboot_memory_map_t const *mem_map = (multiboot_memory_map_t *) multiboot_info->mmap_addr;
uint32_t const mem_map_size = multiboot_info->mmap_length / sizeof(multiboot_memory_map_t);
hk_print_str("BaseAddr - Length - Type\n");
hk_printf("BaseAddr - Length - Type\n");
uint32_t total_available_mem = 0;
uint32_t total_reserved_mem = 0;
uint32_t i = 0;
for (i = 0; i < mem_map_size; i++)
for (uint32_t i = 0; i < mem_map_size; i++)
{
hk_print_hex((uint32_t)((mem_map + i)->addr));
hk_print_str(" - ");
hk_print_hex((uint32_t)((mem_map + i)->len));
hk_print_str(" - ");
hk_print_hex((mem_map + i)->type);
hk_print_str("\n");
hk_printf("0x%x - 0x%X - 0x%x\n",((uint32_t)(mem_map + i)->addr),(uint32_t)((mem_map + i)->len),(uint32_t)(mem_map + i)->type);
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
{
total_reserved_mem += (uint32_t) ((mem_map + i)->len);
@ -55,77 +51,50 @@ void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
total_available_mem += (uint32_t) ((mem_map + i)->len);
}
}
hk_print_str("Total available memory: ");
hk_print_int(total_available_mem);
hk_print_str("B = ");
hk_print_int(total_available_mem/1024);
hk_print_str("KB = ");
hk_print_int(total_available_mem/1024/1024);
hk_print_str("MB\n");
hk_print_str("Total reserved memory: ");
hk_print_int(total_reserved_mem);
hk_print_str("B = ");
hk_print_int(total_reserved_mem/1024);
hk_print_str("KB = ");
hk_print_int(total_reserved_mem/1024/1024);
hk_print_str("MB\n\n");
hk_printf("Total available memory: %uB, %uKB, %uMB.\n",total_available_mem,total_available_mem/1024,total_available_mem/1024/1024);
hk_printf("Total reserved memory: %uB, %uKB, %uMB.\n\n", total_reserved_mem, total_reserved_mem/1024, total_reserved_mem/1024/1024);
}
else
{
hk_print_str("Memory information is currently unavailable.\n\n");
hk_printf("Memory information is currently unavailable.\n\n");
}
//check modules
hk_print_str("*Checking loaded kernel modules...\n");
hk_printf("*Checking loaded kernel modules...\n");
if(multiboot_info->flags & (1 << 3))
{
multiboot_module_t const * mods_list = (multiboot_module_t *)multiboot_info->mods_addr;
uint32_t const mods_count = multiboot_info->mods_count;
hk_print_int(mods_count);
hk_print_str(" module(s) loaded:\n");
hk_print_str("Name - StartAddr - EndAddr\n");
uint32_t i = 0;
for (i = 0; i < mods_count; i++)
hk_printf("%u module(s) loaded:\n", mods_count);
hk_printf("Name - StartAddr - EndAddr\n");
for (uint64_t i = 0; i < mods_count; i++)
{
hk_print_str((char *) (mods_list + i)->cmdline);
hk_print_str(" - ");
hk_print_hex((mods_list + i)->mod_start);
hk_print_str(" - ");
hk_print_hex((mods_list + i)->mod_end);
hk_print_str("\n");
hk_printf("%s - 0x%X - 0x%X\n",(char *) (mods_list + i)->cmdline,(mods_list + i)->mod_start,(mods_list + i)->mod_end);
}
hk_print_str("\n");
hk_printf("\n");
}
else
{
hk_print_str("Module information is currently unavailable.\n\n");
hk_printf("Module information is currently unavailable.\n\n");
}
a:
goto a;
HLT_CPU();
}
void HYPKERNEL32 hk_init_x64(multiboot_info_t const * const multiboot_info)
{
//CHECK MODULE AND LOAD ELF
a:
goto a;
}
void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
void HYPKERNEL32 hk_main(multiboot_info_t* multiboot_info)
{
//init text_position
text_pos = 0;
//detect architecture
hk_print_str("*Checking architecture...\n");
hk_printf("*Checking architecture...\n");
if (hk_support_x64() == 0)
{
hk_print_str("Arch: x86.\n\n");
hk_printf("Arch: x86.\n\n");
hk_init_x86(multiboot_info);
}
else
{
hk_print_str("Arch: x86_64.\n\n");
hk_printf("Arch: x86_64.\n\n");
hk_init_x64(multiboot_info);
}
return;

View File

@ -1,6 +1,5 @@
#include "kdef.h"
#include "mem.h"
#include "print.h"
void HYPKERNEL32 hk_write_segment_descriptor(void * const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr)
{

View File

@ -1,3 +1,4 @@
#include <stdarg.h>
#include "kdef.h"
#include "type.h"
#include "mem.h"
@ -5,12 +6,12 @@
uint32_t text_pos;
uint32_t HYPKERNEL32 hk_str_len(char const * str)
uint32_t HYPKERNEL32 hk_str_len(char const *str)
{
uint32_t length = 0;
if(str == NULL)
if (str == NULL)
return 0;
while(*str != 0)
while (*str != 0)
{
str++;
length++;
@ -18,16 +19,16 @@ uint32_t HYPKERNEL32 hk_str_len(char const * str)
return length;
}
uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2)
uint32_t HYPKERNEL32 hk_str_cmp(char const *str1, char const *str2)
{
if(str1 == NULL || str2 == NULL)
if (str1 == NULL || str2 == NULL)
return 0;
uint32_t length = hk_str_len(str1);
if(length != hk_str_len(str2))
if (length != hk_str_len(str2))
return 0;
while(length--)
while (length--)
{
if(*(str1+length) != *(str2+length))
if (*(str1 + length) != *(str2 + length))
return 0;
}
return 1;
@ -35,24 +36,24 @@ uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2)
void HYPKERNEL32 hk_print_scroll()
{
hk_mem_move((void*)(0xb8000 + get_pos(1,0) * 2), (void*)(0xb8000 + get_pos(0,0) * 2), (80*24)*2);
hk_mem_move((void *) (0xb8000 + get_pos(1, 0) * 2), (void *) (0xb8000 + get_pos(0, 0) * 2), (80 * 24) * 2);
return;
}
void HYPKERNEL32 hk_print_str(char const *str)
void HYPKERNEL32 _print_str(char const *str)
{
if(str == NULL)
if (str == NULL)
return;
while (*str != 0)
{
if(*str == '\n')
if (*str == '\n')
{
text_pos = 80 * (get_row(text_pos) + 1);
if(text_pos > 80 * 25 - 1)
if (text_pos > 80 * 25 - 1)
{
//can't hold
hk_print_scroll();
hk_mem_set((void*)(0xb8000 + 80*24*2), 0, 80 * 2); // clear last row
hk_mem_set((void *) (0xb8000 + 80 * 24 * 2), 0, 80 * 2); // clear last row
text_pos = 80 * 24;
}
str++;
@ -65,8 +66,8 @@ void HYPKERNEL32 hk_print_str(char const *str)
hk_print_scroll();
text_pos = 80 * 24;
}
*((char*)(0xb8000) + text_pos*2) = *str;
*((char*)(0xb8000) + text_pos*2 + 1) = 7;
*((char *) (0xb8000) + text_pos * 2) = *str;
*((char *) (0xb8000) + text_pos * 2 + 1) = 7;
str++;
text_pos++;
}
@ -74,17 +75,12 @@ void HYPKERNEL32 hk_print_str(char const *str)
return;
}
void HYPKERNEL32 hk_print_int(int32_t number)
void HYPKERNEL32 _print_uint(uint32_t number)
{
char arr[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32_t index = 10;
uint32_t isNegative = 0;
char arr[11]; // do not need to initialize
arr[10] = 0; //zero-terminated
uint32_t index = 9;
uint32_t const div = 10;
if (number < 0)
{
isNegative = 1;
number *= -1;
}
while (1)
{
uint32_t quo = number / div;
@ -95,41 +91,128 @@ void HYPKERNEL32 hk_print_int(int32_t number)
if (number == 0)
break;
}
if (isNegative)
{
arr[index] = '-';
hk_print_str(&(arr[index]));
}
else
hk_print_str(&(arr[index+1]));
_print_str(&(arr[index + 1]));
return;
}
void HYPKERNEL32 hk_print_hex(uint32_t number)
void HYPKERNEL32 _print_int(int32_t number)
{
const char lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char arr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32_t index = 9;
char arr[12]; // do not need to initialize
arr[11] = 0; //zero-terminated
uint32_t index = 10;
uint32_t isNegative = 0;
uint32_t const div = 10;
if (number < 0)
{
isNegative = 1;
number *= -1;
}
while (1)
{
int32_t quo = number / div;
int32_t rmd = number % div;
number = quo;
arr[index] = (char) ('0' + rmd);
index--;
if (number == 0)
break;
}
if (isNegative)
{
arr[index] = '-';
_print_str(&(arr[index]));
}
else
_print_str(&(arr[index + 1]));
return;
}
void HYPKERNEL32 _print_hex(uint32_t number, uint32_t captial)
{
char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
char const * const look_up = captial == 1 ? lookup_table_cap : lookup_table;
char arr[9];
arr[8] = 0; //zero-terminated
uint32_t index = 7;
uint32_t const div = 16;
while (1)
{
uint32_t quo = number / div;
uint32_t rmd = number % div;
number = quo;
arr[index--] = lookup_table[rmd];
arr[index--] = look_up[rmd];
if (number == 0)
break;
}
arr[index--] = 'x';
arr[index] = '0';
hk_print_str(&(arr[index]));
_print_str(&(arr[index + 1]));
return;
};
}
void HYPKERNEL32 hk_clear_screen(void)
{
text_pos = 0; // reset text_pos
hk_mem_set((void*)0xb8000, 0, 25*80*2);
hk_mem_set((void *) 0xb8000, 0, 25 * 80 * 2);
return;
}
void HYPKERNEL32 hk_printf(char const *format, ...)
{
va_list args;
va_start(args, format);
char buf[2] = {0, 0};
int32_t d;
uint32_t u;
char* s;
char c;
for(;*format != '\0';format++)
{
if (*format != '%')
{
buf[0] = *format;
_print_str(buf);
continue;
}
format++;
switch (*format)
{
case 'd':
d = va_arg(args, int32_t);
_print_int(d);
break;
case 'u':
u = va_arg(args, uint32_t);
_print_uint(u);
break;
case 's':
s = va_arg(args, char *);
_print_str(s);
break;
case 'c':
c = va_arg(args, int32_t);
buf[0] = c;
_print_str(buf);
break;
case 'x':
u = va_arg(args, uint32_t);
_print_hex(u, 0);
break;
case 'X':
u = va_arg(args, uint32_t);
_print_hex(u, 1);
break;
case '%':
buf[0] = '%';
_print_str(buf);
break;
default:
buf[0] = '%';
_print_str(buf);
format--;
break;
}
}
}

View File

@ -7,9 +7,7 @@
#define get_row(pos) (pos / 80)
#define get_pos(row,col) ((row) * 80 + (col))
void HYPKERNEL32 hk_print_hex(uint32_t number);
void HYPKERNEL32 hk_print_int(int32_t number);
void HYPKERNEL32 hk_print_str(char const *str);
void HYPKERNEL32 hk_printf(char const *format, ...);
uint32_t HYPKERNEL32 hk_str_len(char const * str);
uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2);
void HYPKERNEL32 hk_clear_screen(void);