From 7aea8d20ec8816759c8439fc39d90579fc37e18b Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Wed, 27 Aug 2014 23:10:04 +0200 Subject: cleanup and switched logging to vesa mode console! --- Makefile | 10 +- README.md | 3 +- boot/mbr.asm | 8 +- kernel/floppy.c | 79 ++++++++-------- kernel/interrupts.c | 5 + kernel/kernel.c | 42 +++------ kernel/kernel.h | 3 +- kernel/mem.c | 28 ++---- kernel/pci.c | 29 ++---- kernel/shell.c | 12 +-- kernel/timer.c | 5 +- kernel/vesa.c | 109 +++++++++++++-------- kernel/vmem.c | 2 +- lib/logger/log.c | 22 +++++ lib/logger/log.h | 12 +++ lib/printf/printf.c | 250 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/printf/printf.h | 125 +++++++++++++++++++++++++ makefont.py | 2 +- screenshots/foolos.png | Bin 12592 -> 2718 bytes 19 files changed, 578 insertions(+), 168 deletions(-) create mode 100644 lib/logger/log.c create mode 100644 lib/logger/log.h create mode 100644 lib/printf/printf.c create mode 100644 lib/printf/printf.h diff --git a/Makefile b/Makefile index a512ddb..61d25ec 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ keyboard.o: kernel/keyboard.c gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 vesa.o: kernel/vesa.c - gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 + gcc -ffreestanding -std=gnu99 -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 timer.o: kernel/timer.c gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 @@ -83,7 +83,13 @@ timer.o: kernel/timer.c shell.o: kernel/shell.c gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 -kernel.bin: kernel_entry.o kernel.o console.o interrupts.o keyboard.o timer.o floppy.o x86.o shell.o mem.o vmem.o pci.o e1000.o vesa.o +log.o: lib/logger/log.c + gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 + +printf.o: lib/printf/printf.c + gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0 + +kernel.bin: kernel_entry.o kernel.o console.o interrupts.o keyboard.o timer.o floppy.o x86.o shell.o mem.o vmem.o pci.o e1000.o vesa.o log.o printf.o ld -o $@ -Ttext 0x1000 --oformat binary -melf_i386 $^ -O0 #16bit bootloader! diff --git a/README.md b/README.md index f93aed0..db8e7c4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ VESA and a couple of other things. ![Screenshot of FoolOS](/screenshots/foolos.png?raw=true "FoolOs Kernel") -Copyright M.Idziorek 2014 +Copyright M.Idziorek 2014 unless stated otherwise! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -42,6 +42,7 @@ TODOS Some things I would like to add someday: +* port c lib and gcc * Filesystem (probably FAT) * e1000 driver * networking stack / webserver diff --git a/boot/mbr.asm b/boot/mbr.asm index bb1fc2b..26d13bf 100644 --- a/boot/mbr.asm +++ b/boot/mbr.asm @@ -56,13 +56,13 @@ jmp boot_16 ;start boot process BOOT_DRIVE: db 0xff STR_VERSION: - db "v0.3~",0 + db "Fool Boot Loader v0.3.1~",0 VESA_CHECK1: - db "vesa1.",0 + db " VESA: Get Info.",0 VESA_CHECK2: - db "vesa2.",0 + db " VESA: Get Mode Info.",0 VESA_CHECK3: - db "vesa3.",0 + db " VESA: Set Mode.",0 ;lets put our temporary GDT (Global Descriptor Table) here ;kernel should move this away diff --git a/kernel/floppy.c b/kernel/floppy.c index a373ec7..557df2a 100644 --- a/kernel/floppy.c +++ b/kernel/floppy.c @@ -17,6 +17,10 @@ #include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "floppy" + + #define FLPY_SECTORS_PER_TRACK 18 static volatile int _CurrentDrive=0; @@ -26,7 +30,6 @@ static volatile uint8_t _FloppyDiskIRQ = 0; //! initialize DMA to use phys addr 1k-64k void flpydsk_initialize_dma () { - scr_put_string_nl("dma: initialize direct memory access"); x86_outb (0x0a,0x06); //mask dma channel 2 x86_outb (0xd8,0xff); //reset master flip-flop @@ -39,15 +42,15 @@ void flpydsk_initialize_dma () { x86_outb (0x05, 0x23); x86_outb (0x80, 0); //external page register = 0 x86_outb (0x0a, 0x02); //unmask dma channel 2 + log("dma",FOOLOS_LOG_INFO,"initialized"); } //! prepare the DMA for read transfer void flpydsk_dma_read () { - x86_outb (0x0a, 0x06); //mask dma channel 2 x86_outb (0x0b, 0x56); //single transfer, address increment, autoinit, read, channel 2 x86_outb (0x0a, 0x02); //unmask dma channel 2 - scr_put_string_nl("dma: configured for reading"); + log("dma",FOOLOS_LOG_INFO,"configured for reading"); } //! prepare the DMA for write transfer @@ -56,7 +59,7 @@ void flpydsk_dma_write () { x86_outb (0x0a, 0x06); //mask dma channel 2 x86_outb (0x0b, 0x5a); //single transfer, address increment, autoinit, write, channel 2 x86_outb (0x0a, 0x02); //unmask dma channel 2 - scr_put_string_nl("dma: configured for writing"); + log("dma",FOOLOS_LOG_INFO,"configured for writing"); } // // @@ -157,7 +160,7 @@ void sleep(int i) void flpydsk_motor_on() { - scr_put_string("floppy: starting motor..."); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"starting motor..."); //x86_outb (FLPYDSK_DOR, FLPYDSK_DOR_MASK_DRIVE0_MOTOR | FLPYDSK_DOR_MASK_RESET); x86_outb (FLPYDSK_DOR, 0x1c); sleep(20); @@ -165,7 +168,7 @@ void flpydsk_motor_on() } void flpydsk_motor_off() { - scr_put_string("floppy: stopping motor..."); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stopping motor..."); x86_outb (FLPYDSK_DOR, 0x0c); //x86_outb (FLPYDSK_DOR,FLPYDSK_DOR_MASK_RESET); scr_put_string_nl("ok"); @@ -178,7 +181,7 @@ int flpydsk_calibrate (uint32_t drive) { if (drive >= 4) { - scr_put_string_nl("floppy: ERROR"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ERROR!"); return -2; } @@ -188,7 +191,7 @@ int flpydsk_calibrate (uint32_t drive) { int i; for (i = 0; i < 10; i++) { - scr_put_string_nl("floppy: calibrate"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating"); //! send command flpydsk_send_command ( FDC_CMD_CALIBRATE ); flpydsk_send_command ( drive ); @@ -198,14 +201,14 @@ int flpydsk_calibrate (uint32_t drive) { //! did we fine cylinder 0? if so, we are done if (!cyl) { if(st0 & 0xC0) { - scr_put_string_nl("floppy: calibration FAILED!"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!"); } // flpydsk_control_motor (false); flpydsk_motor_off(); return 0; } } - scr_put_string_nl("floppy: calibration FAILED!"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!"); // flpydsk_control_motor (false); flpydsk_motor_off(); @@ -239,7 +242,7 @@ uint8_t flpydsk_read_data () { if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG ) return x86_inb (FLPYDSK_FIFO); - scr_put_string_nl("floppy: read data fail!"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reading data FAILED!"); } void flpydsk_send_command (uint8_t cmd) { @@ -251,7 +254,7 @@ void flpydsk_send_command (uint8_t cmd) { x86_outb(FLPYDSK_FIFO, cmd); return; } - scr_put_string_nl("floppy: write data fail!"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"writing data FAILED!"); } void flpydsk_drive_data (uint32_t stepr, uint32_t loadt, uint32_t unloadt, int dma ) { @@ -272,7 +275,7 @@ void flpydsk_reset() uint32_t st0, cyl; //! reset the controller - scr_put_string_nl("floppy: reset controller"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reset controller"); flpydsk_disable_controller (); flpydsk_enable_controller (); flpydsk_wait_irq (); @@ -301,7 +304,7 @@ void int_floppy_handler() { X86_IRQ_BEGIN - scr_put_string_nl("floppy: inside interrupt handler."); +// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"handling interrupt"); _FloppyDiskIRQ=1; X86_IRQ_END @@ -309,10 +312,10 @@ void int_floppy_handler() void flpydsk_wait_irq() { - scr_put_string_nl("floppy: wait for irq6"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"waiting for irq6"); while ( _FloppyDiskIRQ == 0); _FloppyDiskIRQ = 0; - scr_put_string_nl("floppy: ok received "); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"irq6 received"); } void flpydsk_check_int (uint32_t* st0, uint32_t* cyl) { @@ -325,12 +328,12 @@ void flpydsk_check_int (uint32_t* st0, uint32_t* cyl) { void flpydsk_write_sector_imp (uint8_t head, uint8_t track, uint8_t sector) { - sector=1; + //sector=1; //! set the DMA for read transfer flpydsk_dma_write (); //flpydsk_drive_data (13, 1, 0xf, 0); - scr_put_string_nl("floppy: writing (head/track/sector)"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"writing head/track/sector"); uint32_t st0, cyl; @@ -372,7 +375,7 @@ void flpydsk_read_sector_imp (uint8_t head, uint8_t track, uint8_t sector) { flpydsk_dma_read (); //flpydsk_drive_data (13, 1, 0xf, 0); - scr_put_string_nl("floppy: reading (head/track/sector)"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reading head/track/sector"); uint32_t st0, cyl; @@ -422,11 +425,7 @@ int flpydsk_seek ( uint32_t cyl, uint32_t head ) int i; for (i = 0; i < 10; i++ ) { - scr_put_string("floppy: seeking (cyl/head) : "); - scr_put_hex(cyl); - scr_put_string("/"); - scr_put_hex(head); - scr_put_string_nl(""); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"seeking cyl: %d, head: %d",cyl,head); //! send the command flpydsk_send_command (FDC_CMD_SEEK); @@ -462,9 +461,7 @@ void flpydsk_lba_to_chs (int lba,int *head,int *track,int *sector) { uint8_t* flpydsk_read_sector (int sectorLBA) { - scr_put_string("floppy: reading sector:"); - scr_put_hex(sectorLBA); - scr_put_string_nl("."); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reading sector: %d",sectorLBA); if (_CurrentDrive >= 4) @@ -495,10 +492,7 @@ uint8_t* flpydsk_read_sector (int sectorLBA) { uint8_t* flpydsk_write_sector (int sectorLBA) { - scr_put_string("floppy: writing sector:"); - scr_put_hex(sectorLBA); - scr_put_string_nl("."); - + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"writing sector: %d",sectorLBA); if (_CurrentDrive >= 4) return 0; @@ -533,8 +527,8 @@ void floppy_init() _CurrentDrive=0; _FloppyDiskIRQ = 0; - - scr_put_string_nl("floppy: init floppy driver."); + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"driver init"); flpydsk_reset (); // flpydsk_drive_data (13, 1, 0xf, 0); @@ -543,18 +537,19 @@ void floppy_init() // // - scr_put_string_nl("floppy: test read (sector 0)."); - flpydsk_read_sector(64); //0x8000 here the data starts! - scr_put_string_nl("floppy: data: "); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test read (sector: 1)"); + flpydsk_read_sector(1); + uint16_t *dma=0xb000; + int i; for(i=0;i<10;i++) - scr_put_hex(dma[i]); - - scr_put_string_nl(""); - - /* - scr_put_string_nl("floppy: test write (sector 100)."); + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test read 0x%04x ",dma[i]); + } + +/* + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test write (sector: 100)"); flpydsk_write_sector(100); */ diff --git a/kernel/interrupts.c b/kernel/interrupts.c index bac687b..b166669 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -1,6 +1,9 @@ #include "interrupts.h" #include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "interrupts" + // the interrupt descriptor table static struct int_desc { @@ -31,6 +34,7 @@ void int_disable() void int_enable() { __asm__("sti"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"up and running"); } @@ -76,6 +80,7 @@ void int_init(uint16_t sel) int_install_ir(i, 0b10001110, sel,&int_def_handler); } + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"initializing..."); } void int_install() diff --git a/kernel/kernel.c b/kernel/kernel.c index c260e80..f4e440f 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -2,6 +2,9 @@ #include "console.h" // this will allow us to write to screen #include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "kernel" + // TODO: cleanup . how can i compile it without the includes!?? /////// @@ -22,7 +25,7 @@ void int_test_handler() { X86_IRQ_BEGIN - scr_put_string("inside software interrupt handler 88"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"inside interrupt handler 88"); sleep(30); X86_IRQ_END @@ -50,27 +53,24 @@ void kernel_main() // is integrated in the kernel image. // vesa_init(0x8300,0x8400,0x7200); - while(1); // never ending loop - // clear console -//! scr_clear(); - - // hello message -//! scr_put_string_nl(KERNEL_HELLO_MESSAGE); -//! scr_put_string_nl(""); + // + // Now Fool OS can say hello :) + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,KERNEL_HELLO_MESSAGE); - //pit config + // + // PIT config (timer) timer_init(); - // we know that here the bootloader placed the mamory map! -//! mem_init(0x7c00+0x400,*((uint16_t *)(0x7c00+0x600))); - mem_init(0x9000); - + // we know that here, the bootloader placed the mamory map! + mem_init(0x7c00+0x400,*((uint16_t *)(0x7c00+0x600))); + // paging (Todo) - vmem_init(); + //vmem_init(); // init and interrupt decriptor table int_init(0x08); + int_install(); // setup custom interrupts @@ -95,7 +95,6 @@ void kernel_main() // now we can enable interrupts back again int_enable(); -//! scr_put_string_nl("interrupts: Interrupts are up and running"); // pci pci_init(); @@ -103,22 +102,9 @@ void kernel_main() // floppy floppy_init(); -//! scr_put_string_nl(""); - - //init shell shell_init(); - // kernel main loop - -// while(1) - // { - //} - - // put some text on monitor! - - - while(1); // never ending loop diff --git a/kernel/kernel.h b/kernel/kernel.h index 5d10738..9f42fdf 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -3,7 +3,8 @@ #include //needed for uint16_t -#define KERNEL_HELLO_MESSAGE "FoolOs 0.0.5" +#define KERNEL_HELLO_MESSAGE "Welcome to FoolOs 0.0.6" + // #define DEBUG #endif diff --git a/kernel/mem.c b/kernel/mem.c index 68880be..b2e674e 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -1,6 +1,9 @@ #define MEM_PRINT_MEMORYMAP #include "kernel.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "mem" + //! 8 blocks per byte #define PMMNGR_BLOCKS_PER_BYTE 8 @@ -208,11 +211,10 @@ void mem_test(int start, int end, int steps) void mem_init(uint16_t *memmap,uint16_t entries) { - scr_put_string("mem: the memory map contains "); - scr_put_hex(entries); - scr_put_string_nl(" entries."); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"the memory map contains %d entries.",entries); // hardcoded memory bitmap!!??! + // todo: fix! _mmngr_memory_map=0x9000; mem_free_blocks=0; pmmngr_init (); @@ -229,21 +231,11 @@ void mem_init(uint16_t *memmap,uint16_t entries) #ifdef MEM_PRINT_MEMORYMAP - scr_put_hex(memmap[8]); - scr_put_string(" : "); - - - scr_put_hex(memmap[1]); - scr_put_string(" "); - scr_put_hex(memmap[0]); - scr_put_string(" "); - - scr_put_string(" - "); - scr_put_hex(memmap[5]); - scr_put_string(" "); - scr_put_hex(memmap[4]); - - scr_put_string_nl(""); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%x : 0x%08x - 0x%08x", + memmap[8], + (((uint32_t)memmap[1])<<16)+memmap[0], + (((uint32_t)memmap[1])<<16)+memmap[0] + +(((uint32_t)memmap[5])<<16)+memmap[4]); #endif diff --git a/kernel/pci.c b/kernel/pci.c index 8aa5eb9..c8bd95d 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -1,5 +1,7 @@ #include "kernel.h" #include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "pci" #define PCI_CONFIG_DATA 0xCFC #define PCI_CONFIG_ADDRESS 0xCF8 @@ -61,23 +63,8 @@ void test_bar(uint8_t bus, uint8_t slot, uint8_t offset) // restore original values pciConfigSet(bus,slot,0,offset,(bar_high<<16)+bar_low); - scr_put_string("e1000: BAR: "); - if(bar_low& 1)scr_put_string("i/o "); - else scr_put_string("mem "); - - - scr_put_hex(bar_high); - scr_put_hex(bar_low); - - scr_put_string(" size: "); - - scr_put_hex(size_high); - scr_put_hex(size_low); - scr_put_string(" => "); - scr_put_hex32(size); - - - scr_put_string_nl(";"); + + log("e1000",FOOLOS_LOG_INFO,"%s bar: (0x%x 0x%x) size: 0x%x" ,bar_low&1?"i/o":"mem",bar_high, bar_low, size); } @@ -91,11 +78,7 @@ uint16_t pciCheck(uint8_t bus, uint8_t slot) if ((vendor = pciConfigReadWord(bus,slot,0,0)) != 0xFFFF) { device = pciConfigReadWord(bus,slot,0,2); - scr_put_string("pci: "); - scr_put_hex(vendor); - scr_put_hex(device); - scr_put_string_nl(";"); - + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d,%d]: vendor: 0x%x / device: 0x%x",bus,slot,vendor,device); // check for: E1000 (82540EM). PCI Ethernet Controller if(vendor==0x8086&&device==0x100e) @@ -126,7 +109,7 @@ uint16_t pciCheck(uint8_t bus, uint8_t slot) void pci_init() { - scr_put_string_nl("pci: scanning pci bus"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"scanning bus"); // todo: recurse on pci to pci bridges! // todo: support multiple pci host controllers! // (check more funcitons of device 0:0) diff --git a/kernel/shell.c b/kernel/shell.c index ebbeb51..2c7fc95 100644 --- a/kernel/shell.c +++ b/kernel/shell.c @@ -1,5 +1,7 @@ #include "kernel.h" #include "interrupts.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "shell" #define COMMAND_LENGTH 255 @@ -55,12 +57,7 @@ void shell_execute() if(1==strcmp(command,"TIME")) { - scr_put_hex(timer16); - scr_put_string(" seconds passed since system start."); - } - else if(1==strcmp(command,"INT")) - { - scr_put_hex(int_unhandled); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d seconds passed since system start.",timer16); } else if(1==strcmp(command,"EIGHT")) { @@ -72,11 +69,10 @@ void shell_execute() } else { - scr_put_string(" unsupported command, sorry!"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"command unknown"); } pos=0; - scr_nextline(); scr_put_string("Command> "); diff --git a/kernel/timer.c b/kernel/timer.c index b4787b9..f2e512c 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -34,6 +34,9 @@ #include "kernel.h" #include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "timer" + static uint64_t timer64=0; static uint8_t timer8=0; uint16_t timer16=0; @@ -89,5 +92,5 @@ void timer_init() __asm__("popa"); - scr_put_string_nl("timer: Configured PIT Channel 0 : Mode 2 : 1/25 s."); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Configured PIT Channel 0 : Mode 2 : 1/25 s."); } diff --git a/kernel/vesa.c b/kernel/vesa.c index 43e0dfb..8bac363 100644 --- a/kernel/vesa.c +++ b/kernel/vesa.c @@ -1,6 +1,10 @@ //http://wiki.osdev.org/GUI +#include #include "kernel.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "vesa" + typedef struct vbeinfo_struct{ char VbeSignature[4]; // == "VESA" uint16_t VbeVersion; // == 0x0300 for VBE 3.0 @@ -42,57 +46,47 @@ typedef struct foolfont_struct }foolfont; - static foolfont *deffont; static vbemodeinfo *VbeModeInfoBlock; +static console_x; +static console_y; + +static console_lines; +static console_cols; + void vesa_init(vbeinfo *info,vbemodeinfo *mode,foolfont *rawfont) { - //the only functionallu important 2 init lines! (rest is log) + //the only functionallu important init lines! (rest is log) VbeModeInfoBlock=mode; deffont=rawfont; - // + console_x=0; + console_y=0; + + int line_height=12; + int col_width=10; + console_lines=mode->Yres/line_height; + console_cols=mode->Xres/col_width; - PutString("Welcome to Fool OS 001",30,30,0xfff00); + // vesa info + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setup complete. vbe version: 0x%x / video mode ptr: 0x%x 0x%x", + info->VbeVersion, info->VideoModePtr[1], info->VideoModePtr[0]); - int i=0; - scr_put_string("vesa: init vbe version: "); - scr_put_hex(info[i].VbeVersion); - scr_put_string(" / videomode ptr: "); - scr_put_hex(info[i].VideoModePtr[0]); - scr_put_hex(info[i].VideoModePtr[1]); - scr_put_string_nl(""); + // vesa info on selected mode: + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"res: %d * %d / banks: %d / attr: 0x%x / bpp: %d / physbase: 0x%x", + mode->Xres, mode->Yres, mode->banks, mode->attributes, mode->bpp,mode->physbase); - int *modeptr=info[i].VideoModePtr[0]; // todo: take segment from vbeinfo! + // vesa modes + // todo: take segment from vbeinfo! +#ifdef FOOLSOS_SHOW_VESAMODES + uint16_t *modeptr=info->VideoModePtr[0]; while(*modeptr!=0xffff&&*modeptr!=0) { - - scr_put_string("vesa: mode supported: "); - scr_put_hex(*modeptr); - scr_put_string_nl(""); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mode supported : 0x%x", (*modeptr)); modeptr++; } - - scr_put_string("vesa: selected mode res: "); - scr_put_hex(mode->Xres); - scr_put_string(" x "); - scr_put_hex(mode->Yres); - scr_put_string_nl(""); - scr_put_string("vesa: selected mode banks: "); - scr_put_hex(mode->banks); - scr_put_string_nl(""); - scr_put_string("vesa: attribs: "); - scr_put_hex(mode->attributes); - scr_put_string_nl(""); - scr_put_string("vesa: physbase: "); - scr_put_hex32(mode->physbase); - scr_put_string_nl(""); - scr_put_string("vesa: bpp: "); - scr_put_hex(mode->bpp); - scr_put_string_nl(""); - - +#endif } @@ -116,11 +110,13 @@ void PutFont(char c, int x,int y, int color) if(c>='A'&&c<='Z')fnt=c-'A'+1; else if(c>='a'&&c<='z')fnt=c-'a'+1; else if(c>='0'&&c<='9')fnt=c-'0'+28; - else if(c=' ')fnt=27; + else if(c==' ')fnt=27; int posx, posy, sizex=8, sizey=10; for(posx=x;posxconsole_cols)PutConsoleNL(); + } + +} +void PutConsoleNL() +{ + console_x=0; + console_y++; + if(console_y>console_lines)console_y=1; + for(int i=0;i + +void log(char *module_name, int prio, char *format_string, ...); + +#endif + diff --git a/lib/printf/printf.c b/lib/printf/printf.c new file mode 100644 index 0000000..23d3d46 --- /dev/null +++ b/lib/printf/printf.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its + * contributors may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "printf.h" + +typedef void (*putcf) (void*,char); +static putcf stdout_putf; +static void* stdout_putp; + + +#ifdef PRINTF_LONG_SUPPORT + +static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) + { + int n=0; + unsigned int d=1; + while (num/d >= base) + d*=base; + while (d!=0) { + int dgt = num / d; + num%=d; + d/=base; + if (n || dgt>0|| d==0) { + *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); + ++n; + } + } + *bf=0; + } + +static void li2a (long num, char * bf) + { + if (num<0) { + num=-num; + *bf++ = '-'; + } + uli2a(num,10,0,bf); + } + +#endif + +static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) + { + int n=0; + unsigned int d=1; + while (num/d >= base) + d*=base; + while (d!=0) { + int dgt = num / d; + num%= d; + d/=base; + if (n || dgt>0 || d==0) { + *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); + ++n; + } + } + *bf=0; + } + +static void i2a (int num, char * bf) + { + if (num<0) { + num=-num; + *bf++ = '-'; + } + ui2a(num,10,0,bf); + } + +static int a2d(char ch) + { + if (ch>='0' && ch<='9') + return ch-'0'; + else if (ch>='a' && ch<='f') + return ch-'a'+10; + else if (ch>='A' && ch<='F') + return ch-'A'+10; + else return -1; + } + +static char a2i(char ch, char** src,int base,int* nump) + { + char* p= *src; + int num=0; + int digit; + while ((digit=a2d(ch))>=0) { + if (digit>base) break; + num=num*base+digit; + ch=*p++; + } + *src=p; + *nump=num; + return ch; + } + +static void putchw(void* putp,putcf putf,int n, char z, char* bf) + { + char fc=z? '0' : ' '; + char ch; + char* p=bf; + while (*p++ && n > 0) + n--; + while (n-- > 0) + putf(putp,fc); + while ((ch= *bf++)) + putf(putp,ch); + } + +void tfp_format(void* putp,putcf putf,char *fmt, va_list va) + { + char bf[12]; + + char ch; + + + while ((ch=*(fmt++))) { + if (ch!='%') + putf(putp,ch); + else { + char lz=0; +#ifdef PRINTF_LONG_SUPPORT + char lng=0; +#endif + int w=0; + ch=*(fmt++); + if (ch=='0') { + ch=*(fmt++); + lz=1; + } + if (ch>='0' && ch<='9') { + ch=a2i(ch,&fmt,10,&w); + } +#ifdef PRINTF_LONG_SUPPORT + if (ch=='l') { + ch=*(fmt++); + lng=1; + } +#endif + switch (ch) { + case 0: + goto abort; + case 'u' : { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int),10,0,bf); + else +#endif + ui2a(va_arg(va, unsigned int),10,0,bf); + putchw(putp,putf,w,lz,bf); + break; + } + case 'd' : { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + li2a(va_arg(va, unsigned long int),bf); + else +#endif + i2a(va_arg(va, int),bf); + putchw(putp,putf,w,lz,bf); + break; + } + case 'x': case 'X' : +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); + else +#endif + ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); + putchw(putp,putf,w,lz,bf); + break; + case 'c' : + putf(putp,(char)(va_arg(va, int))); + break; + case 's' : + putchw(putp,putf,w,0,va_arg(va, char*)); + break; + case '%' : + putf(putp,ch); + default: + break; + } + } + } + abort:; + } + + +void init_printf(void* putp,void (*putf) (void*,char)) + { + stdout_putf=putf; + stdout_putp=putp; + } + +void tfp_printf(char *fmt, ...) + { + va_list va; + va_start(va,fmt); + tfp_format(stdout_putp,stdout_putf,fmt,va); + va_end(va); + } + +static void putcp(void* p,char c) + { + *(*((char**)p))++ = c; + } + + + +void tfp_vsprintf(char* s,char *fmt, va_list va) + { + tfp_format(&s,putcp,fmt,va); + putcp(&s,0); + } + +void tfp_sprintf(char* s,char *fmt, ...) + { + va_list va; + va_start(va,fmt); + tfp_vsprintf(s,fmt,va); + va_end(va); + } + + diff --git a/lib/printf/printf.h b/lib/printf/printf.h new file mode 100644 index 0000000..0e65915 --- /dev/null +++ b/lib/printf/printf.h @@ -0,0 +1,125 @@ +/* +File: printf.h + +Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +---------------------------------------------------------------------- + +This library is realy just two files: 'printf.h' and 'printf.c'. + +They provide a simple and small (+200 loc) printf functionality to +be used in embedded systems. + +I've found them so usefull in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and sprintf. + +The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the +long specifier is also +supported. Note that this will pull in some long math routines (pun intended!) +and thus make your executable noticably longer. + +The memory foot print of course depends on the target cpu, compiler and +compiler options, but a rough guestimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your milage may vary. By hacking the source code you can +get rid of some hunred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf you need to supply your own character output function, +something like : + +void putc ( void* p, char c) + { + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; + } + +Before you can call printf you need to initialize it to use your +character output function with something like: + +init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything realy) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it +is safe to call it from interupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf'. This makes it possible +to use them along with 'stdio.h' printf's in a single source file. +You just need to undef the names before you include the 'stdio.h'. +Note that these are not function like macros, so if you have variables +or struct members with these names, things will explode in your face. +Without variadic macros this is the best we can do to wrap these +fucnction. If it is a problem just give up the macros and use the +functions directly or rename them. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +void init_printf(void* putp,void (*putf) (void*,char)); + +void tfp_printf(char *fmt, ...); +void tfp_sprintf(char* s,char *fmt, ...); +void tfp_vsprintf(char* s,char *fmt, va_list va); + +void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); + +#define printf tfp_printf +#define sprintf tfp_sprintf + +#endif + + + diff --git a/makefont.py b/makefont.py index be3c072..5d5d419 100644 --- a/makefont.py +++ b/makefont.py @@ -24,7 +24,7 @@ while True: b+="1" if l==8: - print b +# print b l=0 o.write(chr(int(b,2))) b="" diff --git a/screenshots/foolos.png b/screenshots/foolos.png index d07854c..f4b23b4 100644 Binary files a/screenshots/foolos.png and b/screenshots/foolos.png differ -- cgit v1.2.3