From 7cb940e48500e797849cba7fd69f67b47cc4602f Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Tue, 14 Sep 2021 18:30:00 +0300 Subject: [PATCH] CTAOS v2 --- include/system.h | 104 ------- init.c | 37 --- kernel.bin | Bin 12288 -> 0 bytes kernel/clock/cmos.h | 25 ++ kernel/clock/pictimer.c | 76 +++++ kernel/clock/time.c | 143 +++++++++ compile.bat => kernel/compile.bat | 5 +- console.o => kernel/console.o | Bin include/console.h => kernel/include/conio.h | 40 ++- kernel/include/sys/declarat.h | 40 +++ kernel/include/system.h | 85 ++++++ kernel/kernel.bin | Bin 0 -> 16384 bytes kernel/kernel/epilogue.c | 8 + gdt.c => kernel/kernel/gdt.c | 0 idt.c => kernel/kernel/idt.c | 0 irq.c => kernel/kernel/irq.c | 23 +- isrs.c => kernel/kernel/isrs.c | 39 ++- kernel/kernel/memory.c | 4 + kernel/kernel/prologue.c | 61 ++++ kernel/keyboard/key_list.txt | 135 +++++++++ kernel/keyboard/keyb.c | 60 ++++ kernel/keyboard/keyus.c | 179 +++++++++++ kernel/keyboard/keyus.h | 137 +++++++++ link.ld => kernel/link.ld | 0 loader.asm => kernel/loader.asm | 29 ++ kernel/loader.o | Bin 0 -> 2348 bytes kernel/main.c | 18 ++ kernel/main.o | Bin 0 -> 20986 bytes kernel/shell/apps.h | 122 ++++++++ kernel/shell/shell.c | 81 +++++ keyus.c | 209 ------------- loader.o | Bin 2226 -> 0 bytes main.c | 65 ---- main.o | Bin 12679 -> 0 bytes stage1/MAKE.PIF | Bin 0 -> 967 bytes stage1/bootload.asm | 314 ++++++++++++++++++++ stage1/bootload.bin | Bin 0 -> 512 bytes stage1/make.bat | 18 ++ stage2/MAKE.BAT | 15 + stage2/a20.inc | 103 +++++++ stage2/common.inc | 17 ++ stage2/fat12.inc | 243 +++++++++++++++ stage2/floppy16.inc | 117 ++++++++ stage2/gdt.inc | 68 +++++ stage2/stage2.asm | 158 ++++++++++ stage2/stage2.cta | Bin 0 -> 1012 bytes stage2/stdio.inc | 298 +++++++++++++++++++ timer.c | 52 ---- 48 files changed, 2621 insertions(+), 507 deletions(-) delete mode 100644 include/system.h delete mode 100644 init.c delete mode 100644 kernel.bin create mode 100644 kernel/clock/cmos.h create mode 100644 kernel/clock/pictimer.c create mode 100644 kernel/clock/time.c rename compile.bat => kernel/compile.bat (89%) rename console.o => kernel/console.o (100%) rename include/console.h => kernel/include/conio.h (83%) create mode 100644 kernel/include/sys/declarat.h create mode 100644 kernel/include/system.h create mode 100644 kernel/kernel.bin create mode 100644 kernel/kernel/epilogue.c rename gdt.c => kernel/kernel/gdt.c (100%) rename idt.c => kernel/kernel/idt.c (100%) rename irq.c => kernel/kernel/irq.c (92%) rename isrs.c => kernel/kernel/isrs.c (77%) create mode 100644 kernel/kernel/memory.c create mode 100644 kernel/kernel/prologue.c create mode 100644 kernel/keyboard/key_list.txt create mode 100644 kernel/keyboard/keyb.c create mode 100644 kernel/keyboard/keyus.c create mode 100644 kernel/keyboard/keyus.h rename link.ld => kernel/link.ld (100%) rename loader.asm => kernel/loader.asm (95%) create mode 100644 kernel/loader.o create mode 100644 kernel/main.c create mode 100644 kernel/main.o create mode 100644 kernel/shell/apps.h create mode 100644 kernel/shell/shell.c delete mode 100644 keyus.c delete mode 100644 loader.o delete mode 100644 main.c delete mode 100644 main.o create mode 100644 stage1/MAKE.PIF create mode 100644 stage1/bootload.asm create mode 100644 stage1/bootload.bin create mode 100644 stage1/make.bat create mode 100644 stage2/MAKE.BAT create mode 100644 stage2/a20.inc create mode 100644 stage2/common.inc create mode 100644 stage2/fat12.inc create mode 100644 stage2/floppy16.inc create mode 100644 stage2/gdt.inc create mode 100644 stage2/stage2.asm create mode 100644 stage2/stage2.cta create mode 100644 stage2/stdio.inc delete mode 100644 timer.c diff --git a/include/system.h b/include/system.h deleted file mode 100644 index 87af581..0000000 --- a/include/system.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef __SYSTEM_H -#define __SYSTEM_H - -// Data type declarations -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned int dword; - -/* This defines what the stack looks like after an ISR was running */ -typedef struct -{ - unsigned int gs, fs, es, ds; /* pushed the segs last */ - unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ - unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ - unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ -} regs; - - -byte *TextVideoRam; -int cursor_x, cursor_y; -int current_mode_width; -int current_mode_height; - -// System functions declaration -void system_init(); -void *memcpy(void *dest, const void *src, int count); -void *memset(void *dest, char val, int count); -unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); -int strlen (const char *str); -byte inportb (word _port); -byte inb (word _port); -void outportb (word _port, byte _data); -void outb (word _port, byte _data) ; - -// GDT, IDT, ISRs, IRQ functions declarations -void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); -void gdt_install(); - -void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); -void idt_install(); - -void isrs_install(); - -void irq_install_handler(int irq, void (*handler)(regs *r)); -void irq_uninstall_handler(int irq); -void irq_install(); - - -// Initialize system - - -void *memcpy(void *dest, const void *src, int count) -{ - const char *sp = (const char *)src; - char *dp = (char *)dest; - for(; count != 0; count--) *dp++ = *sp++; - return dest; -} - -void *memset(void *dest, char val, int count) -{ - char *temp = (char *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - -unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) -{ - unsigned short *temp = (unsigned short *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - - -// strlen -- Get lenght of str -int strlen (const char *str) -{ - int i; - for (i = 0; str[i]!=0; i++) {} - return i; -} - - -byte inportb (word _port) { - byte rv; - __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); - return rv; -} -byte inb (word _port) { - byte rv; - __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); - return rv; -} - - -void outportb (word _port, byte _data) { - __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); -} -void outb (word _port, byte _data) { - __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); -} - - -#endif \ No newline at end of file diff --git a/init.c b/init.c deleted file mode 100644 index 9dcd6ef..0000000 --- a/init.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - - -void system_init() -{ - // Detect if color/monochrome screen - char c = (*(volatile unsigned short*)0x410)&0x30; - if (c==0x30) TextVideoRam = (byte *)0xb0000; - else TextVideoRam = (byte *)0xb8000; - - // Reset cursor, use 80x25 text video mode - current_mode_width = 80; - current_mode_height = 25; - cursor_x = cursor_y = 0; - - // Install GDT, IDT, ISRs and IRQs; Enable interrupts - gdt_install(); - idt_install(); - isrs_install(); - irq_install(); - __asm__ __volatile__ ("sti"); - - // Install PIT timer - timer_ticks = 0; - irq_install_handler(0, timer_handler); - timer_phase (100); - - // Install keyboard - kb_modifier_status = 0; - kb_lights_status = 0xFF; kb_update_LED(); - kb_lights_status = 0; kb_update_LED(); - irq_install_handler(1, kb_handler); - - // mouse_driver(); - - -} \ No newline at end of file diff --git a/kernel.bin b/kernel.bin deleted file mode 100644 index cb04e41ef38e9bee9548efd8929e9ac22b77c5f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeHMe{@q-o_|S`Hnb@(g_IU4@QMLjpji3g0tPK@MZ^k$6j6&xXp^R)BsF;f{Dsxf zF=@AK$8l$8XV+c8v%9W)Ts%8xIH)sDLy$5$J63lc(RD`rx%W{7Ms}u1mF(wx-+LiZ z&dk}fyZ^Q4+`RAo+|T{~y7#_!@9j?nmrYP+34$;%V0_{EX?cP{7+bgg6RThYhEj{t zp~~#HWrCoLrPFEAP%8Otg72_R*n48{;NFva+1}w(8^E^+DbX142Mh<{AWn zB!ePpl2MtWNqLG@lT31KZ}$j{ApEQ z;?H8`U-)yP@*IB(0a4kfNjByCnpC3vsU}TQ9@nJF$}UZ^D?v>vRoXOZigLFml_@Sw zDpyu%(p1H%NmnTgHEEhsrAZaa3{9G@*fnW}Qm9EY6$rwX8TsNq@!9OeCQiBzKUicF z(!+O(|0wP+nCW@!s0GwFC`VEzmdZ>lvof(ysV!p5Mzh8c?CvIyr8& z)i3*1^mi@yrif$dYjW6nH#@97KbMO+Ctd-pg?J7runmBJd#kife%#Gp!UmbqJka<{>T2e?i!s;s}mf@}aq)P2s{jPZMwe{k`f9to~Hn^DgQab%2 zb?z-504MpOsj#>U0{2Vpo;X(ho5XqX;Ctf1BeA2_WvNHz_nW5mm6Fb5CZnKA@g}38 zAvS32D|G=E4|2=P-h1>N4C`eV_Yb47?iu=xT`1peS6wcL{eXe3=4mvgHg1CVoen$3 zvm6sa>TPm367PrySMXrY_AMdHNOMKpv|BUOZ<-r_FZq#a!fRTxnpYZH?!E6G8fS~f z$;05NiD+_I<5pJ+W}x0C9>Rna4?XNC-%pvmfse&*Gg}3By2lEm16R6MRaMQA@6=|G+4yrrv}!Qh5b^x+zVMnk3m# zfhorm)SJI&P`;i|vBy57xtVz5v5)xk?M)lSR|Z{a8Cg7$*XVG#*biZ)q1QAccGSLS zF!}+{R3__41eRz8S2%+!r0$#gP4isr`AkPEI{qi`NHfjSn+NlDBC-l(tG5A@;iw6m z(=C)|P;Btjj-f2))H#}yzto(3=Z;OhvmXZ3⪼e&sXfUgkh{5YIKOT*DYLx=j6pp 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 +#include "time.c" +int timer_ticks = 0; +int timer_hz; + +void timer_phase(int hz) +{ + int divisor = 1193180/hz; // Calculate the divisor + outportb(0x43, 0x36); // Set our command byte 0x36 + outportb(0x40, divisor&0xFF); // Set low byte + outportb(0x40, divisor>>8); // Set high byte + timer_hz = hz; +} + +void clock_show (int uptime_secs) +{ + int i; + for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F); + puts_pos_font (64, 0, "Uptime:", 0x02, 0x0E); + + unsigned int uptime; + + uptime = uptime_secs%60; // Seconds + uptime += 100* ((uptime_secs/60)%60); // Minutes + uptime += 10000*(uptime_secs/3600); // Hours + + for (i=79;i>71;i--) { + if (i==77 || i==74) { + if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F); + else putc_pos_font(i, 0, ' ', 0x02, 0x0F); + } + else { + putc_pos_font(i, 0, (uptime%10)+'0', 0x02, 0x0F); + uptime/=10; + } + } + + // PRINT CURRENT TIME + uptime = clock.seconds; // Seconds + uptime += 100* clock.minutes; // Minutes + uptime += 10000*clock.hours; // Hours + + for (i=9;i>1;i--) { + if (i==7 || i==4) { + if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F); + else putc_pos_font(i, 0, ' ', 0x02, 0x0F); + } + else { + putc_pos_font(i,0, (uptime%10)+'0', 0x02, 0x0F); + uptime/=10; + } + } + if (clock.am_pm==0) puts_pos_font(10, 0, "am", 0x02, 0x0F); + else puts_pos_font(10, 0, "pm", 0x02, 0x0F); + + // PRINT DATE + putc_pos_font(32, 0, (clock.day/10)+'0', 0x02, 0x0E); + putc_pos_font(33, 0, (clock.day%10)+'0', 0x02, 0x0E); + puts_pos_font(35, 0, (char*)clock_months[clock.month], 0x02, 0x0F); + putc_pos_font(35+strlen(clock_months[clock.month])+1, 0, (clock.century/10)+'0', 0x02, 0x0E); + putc_pos_font(35+strlen(clock_months[clock.month])+2, 0, (clock.century%10)+'0', 0x02, 0x0E); + putc_pos_font(35+strlen(clock_months[clock.month])+3, 0, (clock.year/10)+'0', 0x02, 0x0E); + putc_pos_font(35+strlen(clock_months[clock.month])+4, 0, (clock.year%10)+'0', 0x02, 0x0E); + +} + + +void timer_handler(regs *r) +{ + timer_ticks++; + + if (timer_ticks % timer_hz == 0) { + clock_show (timer_ticks / timer_hz); + clock_inc(); + } +} \ No newline at end of file diff --git a/kernel/clock/time.c b/kernel/clock/time.c new file mode 100644 index 0000000..5b0e3a2 --- /dev/null +++ b/kernel/clock/time.c @@ -0,0 +1,143 @@ +#ifndef __TIME_C +#define __TIME_C + +#include "cmos.h" + +static const char* clock_months[] = {0, + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; +static const char* clock_weekdays[] = {0, + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + +byte clock_months_len[] = { + 0, + 31, // January + 28, // February + 31, // March + 30, // April + 31, // May + 30, // June + 31, // July + 31, // August + 30, // September + 31, // October + 30, // November + 31 // December +}; + +typedef struct { + byte seconds; + byte minutes; + byte hours; + byte weekday; + byte day; + byte month; + byte year; + byte century; + byte am_pm; + +} TIME; +volatile static TIME clock; + +void RTC_get_time() +{ + cmos_read(); + + if ((cmos_data[0x0b]&4)==0) // BCD = true; + { + clock.seconds = (cmos_data[0x00]%16) + 10*(cmos_data[0x00]/16); + clock.minutes = (cmos_data[0x02]%16) + 10*(cmos_data[0x02]/16); + if ((cmos_data[0x0b]&2)==0) { // AM/PM + if (cmos_data[0x04]&80) { // pm + clock.hours = ((cmos_data[0x04]-0x80)%16) + 10*((cmos_data[0x04]-0x80)/16); + clock.am_pm = 1; + } + else { // am + clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16); + clock.am_pm = 0; + } + } + else { // 24 hours + clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16); + if (clock.hours > 12) { + clock.am_pm = 1; + clock.hours -= 12; + } + else clock.am_pm = 0; + } + + clock.weekday = (cmos_data[0x06]%16) + 10*(cmos_data[0x06]/16); + clock.day = (cmos_data[0x07]%16) + 10*(cmos_data[0x07]/16); + clock.month = (cmos_data[0x08]%16) + 10*(cmos_data[0x08]/16); + clock.year = (cmos_data[0x09]%16) + 10*(cmos_data[0x09]/16); + clock.century = (cmos_data[0x32]%16) + 10*(cmos_data[0x32]/16); + } + + else {//BCD = false; + clock.seconds = cmos_data[0x00]; + clock.minutes = cmos_data[0x02]; + if ((cmos_data[0x0b]&2)==0) { // AM/PM + if (cmos_data[0x04]&80) { // pm + clock.hours = cmos_data[0x04]-0x80; + clock.am_pm = 1; + } + else { // am + clock.hours = cmos_data[0x04]; + clock.am_pm = 0; + } + } + else { // 24 hours + clock.hours = cmos_data[0x02]; + if (clock.hours > 12) { + clock.am_pm = 1; + clock.hours -= 12; + } + else clock.am_pm = 0; + } + clock.weekday = cmos_data[0x06]; + clock.day = cmos_data[0x07]; + clock.month = cmos_data[0x08]; + clock.year = cmos_data[0x09]; + clock.century = cmos_data[0x32]; + } + // Leap years + if (clock.year % 4 == 0) clock_months_len[2]=29; + +} + +void clock_inc() +{ + // New minute + if (++clock.seconds > 59) { + clock.seconds = 0; + // New hour + if (++clock.minutes > 59) { + clock.minutes = 0; + clock.hours++; + if (clock.hours == 12 && clock.am_pm == 1) { // 11:59pm -> 0:00am + clock.hours = 0; clock.am_pm = 0; + // New day + clock.weekday = 1+(clock.weekday%7); + // New month + if (++clock.day > clock_months_len[clock.month]) { + clock.day = 1; + // New year + if (++clock.month>12) { + clock.month = 1; + // New century + if (++clock.year > 99) { + clock.year = 0; + clock.century++; + } + } + } + } + else if (clock.hours == 12 && clock.am_pm == 0) // 11:59am -> 12:00pm + clock.am_pm = 1; + else if (clock.hours == 13 && clock.am_pm == 1) // 12:59pm -> 1:59pm + clock.hours = 1; + } + } +} + +#endif \ No newline at end of file diff --git a/compile.bat b/kernel/compile.bat similarity index 89% rename from compile.bat rename to kernel/compile.bat index 8b34431..dcc17a1 100644 --- a/compile.bat +++ b/kernel/compile.bat @@ -10,7 +10,7 @@ set djgpp_path=C:\DJGPP\bin rem Compile loader %nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm rem Compile main Kernel -%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c +%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c rem OTHER GCC/NASM SOURCES GO HERE @echo on @@ -19,4 +19,5 @@ rem OTHER GCC/NASM SOURCES GO HERE @echo Done! @pause -copy C:\CTAOS\KERNEL.BIN C:\SHARE +copy KERNEL.BIN C:\SHARE +copy KERNEL.BIN A:\KERNEL.CTA \ No newline at end of file diff --git a/console.o b/kernel/console.o similarity index 100% rename from console.o rename to kernel/console.o diff --git a/include/console.h b/kernel/include/conio.h similarity index 83% rename from include/console.h rename to kernel/include/conio.h index 4630fe8..b2718b1 100644 --- a/include/console.h +++ b/kernel/include/conio.h @@ -1,11 +1,13 @@ #include -#ifndef __CONSOLE_H -#define __CONSOLE_H +#ifndef __CONIO_H +#define __CONIO_H #define _ATTRIB 0x0F byte default_background, default_foreground; +char hex[] = "0123456789ABCDEF"; + // Change cursor position void text_mode_cursor(int x, int y) @@ -55,7 +57,15 @@ void scroll(int n) } -void _endl() +void prev_line() +{ + cursor_x = 79; + if (--cursor_y < 0) { + cursor_y = 0; cursor_x=0; + } +} + +void next_line() { cursor_x = 0; if (++cursor_y >=25) { @@ -78,9 +88,9 @@ void putc_pos(int x, int y, char c) // Put character on screen in the current cursor position; different font colors void putc_font(char c, byte back, byte fore) { - if (cursor_x > current_mode_width) _endl(); + if (cursor_x >= current_mode_width) next_line(); - if (c == '\n') {_endl(); return;}; + if (c == '\n') {next_line(); return;}; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4); cursor_x++; @@ -88,9 +98,9 @@ void putc_font(char c, byte back, byte fore) // Put character on screen in the current cursor position; default font colors void putc(char c) { - if (cursor_x > current_mode_width) _endl(); + if (cursor_x >= current_mode_width) next_line(); - if (c == '\n') {_endl(); return;}; + if (c == '\n') {next_line(); return;}; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c; cursor_x++; } @@ -125,9 +135,8 @@ void puts_font(char *str, byte back, byte fore) putc_font(str[i], back, fore); } -void put_hex(int x, int y, unsigned int alpha) +void put_hex(unsigned int alpha) { - char hex[] = "0123456789ABCDEF"; char nr[9]; int i; for (i = 7; i >= 0; i--) { @@ -135,7 +144,18 @@ void put_hex(int x, int y, unsigned int alpha) alpha /= 16; } nr[8] = 0; - puts_pos(x, y, nr); + puts(nr); +} +void put_hex_pos(int x, int y, unsigned int alpha) +{ + char nr[9]; + int i; + for (i = 7; i >= 0; i--) { + nr[i] = hex[alpha%16]; + alpha /= 16; + } + nr[8] = 0; + puts_pos(x,y,nr); } void put_bin (int x, int y, byte xz) diff --git a/kernel/include/sys/declarat.h b/kernel/include/sys/declarat.h new file mode 100644 index 0000000..28fa675 --- /dev/null +++ b/kernel/include/sys/declarat.h @@ -0,0 +1,40 @@ +// Data type declarations +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int dword; + +/* This defines what the stack looks like after an ISR was running */ +typedef struct +{ + unsigned int gs, fs, es, ds; /* pushed the segs last */ + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ + unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ + unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ +} regs; + + +// Functions +void system_init(); +void *memcpy(void *dest, const void *src, int count); +void *memset(void *dest, char val, int count); +unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); +int strlen (const char *str); +byte inportb (word _port); +byte inb (word _port); +void outportb (word _port, byte _data); +void outb (word _port, byte _data) ; + +void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); +void gdt_install(); + +void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); +void idt_install(); + +void isrs_install(); + +void irq_install_handler(int irq, void (*handler)(regs *r)); +void irq_uninstall_handler(int irq); +void irq_install(); +void kb_handler(regs *r); +void reboot(); +void kb_waitin(); \ No newline at end of file diff --git a/kernel/include/system.h b/kernel/include/system.h new file mode 100644 index 0000000..9ba8159 --- /dev/null +++ b/kernel/include/system.h @@ -0,0 +1,85 @@ +#ifndef __SYSTEM_H +#define __SYSTEM_H +#include + +#define true 1 +#define false 0 + +byte *TextVideoRam; +volatile static int cursor_x, cursor_y; +int current_mode_width; +int current_mode_height; + +void *memcpy(void *dest, const void *src, int count) +{ + const char *sp = (const char *)src; + char *dp = (char *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, char val, int count) +{ + char *temp = (char *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) +{ + unsigned short *temp = (unsigned short *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + + +// strlen -- Get lenght of str +int strlen (const char *str) +{ + int i; + for (i = 0; *str!=0; str++) i++; + return i; +} + +int strcmp(const char *pStr1, const char *pStr2) +{ + char c1, c2; + int v; + + do { + c1 = *pStr1++; + c2 = *pStr2++; + /* the casts are necessary when pStr1 is shorter & char is signed */ + v = (unsigned int)c1 - (unsigned int)c2; + } while ((v == 0) && (c1 != '\0')); + + return v; +} + + + +byte inportb (word _port) { + byte rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} +byte inb (word _port) { + byte rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +static inline void iowait() { + asm volatile ("outb %al, $0x80"); +} + + +void outportb (word _port, byte _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} +void outb (word _port, byte _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} + + +#endif \ No newline at end of file diff --git a/kernel/kernel.bin b/kernel/kernel.bin new file mode 100644 index 0000000000000000000000000000000000000000..a50d6ed3038094d9ad6c727c92bc40a5df9a7c24 GIT binary patch literal 16384 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 n0+%9iDFT-wa47 -#include extern void isr0(); extern void isr1(); @@ -132,30 +131,30 @@ void fault_handler(regs *r) puts (" Blue Screen Of Death\n"); int i; for (i = 79; i>=0; i--) putc('='); puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C); - puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex(15, 4, r->gs); - puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex(15, 5, r->fs); - puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex(15, 6, r->es); - puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex(15, 7, r->ds); + puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs); + puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs); + puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es); + puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds); - puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex(45, 4, r->edi); - puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex(45, 5, r->esi); - puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex(45, 6, r->ebp); - puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex(45, 7, r->esp); + puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi); + puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi); + puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp); + puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp); - puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex(15, 9, r->eax); - puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex(15, 10, r->ebx); - puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex(45, 9, r->ecx); - puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex(45, 10, r->edx); + puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax); + puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx); + puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx); + puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx); - puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex(17, 12, r->int_no); - puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex(24, 14, r->err_code); + puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no); + puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(24, 14, r->err_code); puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]); - puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex(17, 17, r->eip); - puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex(17, 18, r->cs); - puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex(17, 19, r->eflags); - puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex(17, 20, r->useresp); - puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex(17, 21, r->ss); + puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip); + puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs); + puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags); + puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp); + puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss); puts_pos_font (29, 24, "!!! System Halted !!!", 0x01, 0x0C); for (;;); diff --git a/kernel/kernel/memory.c b/kernel/kernel/memory.c new file mode 100644 index 0000000..b5d21e7 --- /dev/null +++ b/kernel/kernel/memory.c @@ -0,0 +1,4 @@ +extern unsigned long* read_cr0(); +extern unsigned long* read_cr3(); +extern void write_cr0(unsigned long* alpha); +extern void write_cr3(unsigned long* alpha); \ No newline at end of file diff --git a/kernel/kernel/prologue.c b/kernel/kernel/prologue.c new file mode 100644 index 0000000..f0eb980 --- /dev/null +++ b/kernel/kernel/prologue.c @@ -0,0 +1,61 @@ +#include +#include "gdt.c" +#include "idt.c" +#include "isrs.c" +#include "irq.c" + +void system_init() +{ + // Detect if color/monochrome screen + char c = (*(volatile unsigned short*)0x410)&0x30; + if (c==0x30) TextVideoRam = (byte *)0xb0000; + else TextVideoRam = (byte *)0xb8000; + + // Reset cursor, use 80x25 text video mode + current_mode_width = 80; + current_mode_height = 25; + cursor_x = cursor_y = 0; + + // Install GDT, IDT, ISRs and IRQs; Enable interrupts + gdt_install(); + idt_install(); + isrs_install(); + irq_install(); + RTC_get_time(); + __asm__ __volatile__ ("sti"); + + // Install PIT timer + timer_ticks = 0; + timer_phase (100); + irq_install_handler(0, timer_handler); + + // Install keyboard (part 1): install IRQ1 and start BAT test + kb_modifier_status = 0; + irq_install_handler(1, kb_handler); + kb_waitin(); outportb(0x60, 0xFF); // Reset kb + + + // other drivers come here!!; + + + + // Install keyboard (part 2): BAT test results & set repeat rates + byte temp; + do temp = inportb(0x60); + while (temp!=0xAA && temp!=0xFC); + // KB failed BAT TEST + if (temp == 0xFC) puts_font("\nKeyboard error: failed BAT test.", 0x07, 0x0C); + kb_set_repeat(1, 11); + + // Install keyboard (part 3): set scancode set 2 + kb_set_scancodeset(2); // Set new scancode set + + kb_waitin(); outportb(0x64, 0x20); // Get "Command byte" + do { temp = inportb(0x60); + } while (temp==0xFA || temp==0xAA); + + temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion + kb_waitin(); outportb(0x64, 0x60); // Function to write cmd byte + kb_waitin(); outportb(0x60, temp); // Send it + memset(kb_array, 0, 16); +} \ No newline at end of file diff --git a/kernel/keyboard/key_list.txt b/kernel/keyboard/key_list.txt new file mode 100644 index 0000000..5ff143e --- /dev/null +++ b/kernel/keyboard/key_list.txt @@ -0,0 +1,135 @@ +*0x00 Pause/Break +0x01 F9 +0x02 F7 +0x03 F5 +0x04 F3 +0x05 F1 +0x06 F2 +0x07 F12 +0x08 Print Screen +0x09 F10 +0x0A F8 +0x0B F6 +0x0C F4 +0x0D Tab +0x0E `~ +0x0F + +0x10 +0x11 +0x12 +0x13 +0x14 +0x15 Q +0x16 1! +0x17 +0x18 +0x19 +0x1A Z +0x1B S +0x1C A +0x1D W +0x1E 2@ +0x1F LeftWin + +0x20 +0x21 C +0x22 X +0x23 D +0x24 E +0x25 4$ +0x26 3# +0x27 RightWin +0x28 +0x29 Space +0x2A V +0x2B F +0x2C T +0x2D R +0x2E 5% +0x2F Menu + +0x30 +0x31 N +0x32 B +0x33 H +0x34 G +0x35 Y +0x36 6^ +0x37 +0x38 +0x39 +0x3A M +0x3B J +0x3C U +0x3D 7& +0x3E 8* +0x3F + +0x40 +0x41 ,< +0x42 K +0x43 I +0x44 O +0x45 0) +0x46 9( +0x47 +0x48 +0x49 .> +0x4A /? +0x4B L +0x4C ;: +0x4D P +0x4E -_ +0x4F + +0x50 +0x51 +0x52 '" +0x53 +0x54 [{ +0x55 =+ +0x56 +0x57 +0x58 +0x59 Numpad Enter +0x5A Enter +0x5B ]} +0x5C +0x5D \| +0x5E End +0x5F Left + +0x60 Home +0x61 Insert +0x62 Delete +0x63 Down +0x64 Right +0x65 Up +0x66 Backspace +0x67 PageDown +0x68 PageUp +0x69 Numpad 1 (end) +0x6A Numpad / +0x6B Numpad 4 (left) +0x6C Numpad 7 (Home) +0x6D +0x6E +0x6F + +0x70 Numpad 0 (insert) +0x71 Numpad . (del) +0x72 Numpad 2 (down) +0x73 Numpad 5 +0x74 Numpad 6 (right) +0x75 Numpad 8 (up) +0x76 Esc +0x77 +0x78 F11 +0x79 Numpad + +0x7A Numpad 3 (pgdwn) +0x7B Numpad - +0x7C Numpad * +0x7D Numpad 9 (pgup) +0x7E +0x7F \ No newline at end of file diff --git a/kernel/keyboard/keyb.c b/kernel/keyboard/keyb.c new file mode 100644 index 0000000..3ab763c --- /dev/null +++ b/kernel/keyboard/keyb.c @@ -0,0 +1,60 @@ + + +void kb_test() +{ + byte temp=0, secs=0; + + puts("\nTHIS WILL TEST FEW COMMANDS OF THE PS/2 KEYBOARD.\n"); + + + puts("\nEcho... "); + while ((inportb(0x64)&2)!=0); + outportb(0x60, 0xEE); +/* while ((inportb(0x64)&1)!=0); + temp = inportb(0x60); + putc_font('[', 0x07, 0x02); + putc_font(hex[temp/16], 0x07, 0x02); + putc_font(hex[temp%16], 0x07, 0x02); + putc_font(']', 0x07, 0x02);*/ + + + puts("\nSet LEDs - SCROLL on... "); + while ((inportb(0x64)&2)!=0); + outportb(0x60, 0xED); +/* while ((inportb(0x64)&2)!=0); + outportb(0x60, 1); + while ((inportb(0x64)&1)!=0); + temp = inportb(0x60);*/ + putc_font('[', 0x07, 0x02); + putc_font(hex[temp/16], 0x07, 0x02); + putc_font(hex[temp%16], 0x07, 0x02); + putc_font(']', 0x07, 0x02); + + + puts("\nGet current scancode set... "); + while ((inportb(0x64)&2)!=0); + outportb(0x60, 0xF0); + while ((inportb(0x64)&2)!=0); + outportb(0x60, 0); + +/* while ((inportb(0x64)&1)!=0); + temp = inportb(0x60); + putc_font('[', 0x07, 0x02); + putc_font(hex[temp/16], 0x07, 0x02); + putc_font(hex[temp%16], 0x07, 0x02); + putc_font(']', 0x07, 0x02);*/ + + + puts("\nTurning on 2 leds (don't know which ones :P)... "); + while ((inportb(0x64)&2)!=0); + outportb(0x60, 0xED); + while ((inportb(0x64)&2)!=0); + outportb(0x60, (byte)1|2); + /* while ((inportb(0x64)&1)!=0); + temp = inportb(0x60); + putc_font('[', 0x07, 0x02); + putc_font(hex[temp/16], 0x07, 0x02); + putc_font(hex[temp%16], 0x07, 0x02); + putc_font(']', 0x07, 0x02);*/ + +} \ No newline at end of file diff --git a/kernel/keyboard/keyus.c b/kernel/keyboard/keyus.c new file mode 100644 index 0000000..392a4ff --- /dev/null +++ b/kernel/keyboard/keyus.c @@ -0,0 +1,179 @@ +#include "keyus.h" + +// kb_key_return 4-byte structure +typedef struct { + byte status; + byte lights; + byte scancode; + byte character; +} kb_key; + +byte kb_array[16]; +volatile static byte kb_newdata; + +/*********DEBUG**************/ +void kb_print_binary(int x, int y, byte what) +{ + char arr[9]; int i; + for (i = 7; i>=0; i--, what/=2) + arr[i] = (what%2) + '0'; + + arr[8] = 0; + + puts_pos(x,y,arr); + +} +/*********DEBUG**************/ + +void kb_set_key(byte scancode, byte val) +{ + byte pos = scancode/8; + byte offset = scancode%8; + + if (val) { + kb_array[pos] |= 1<', '?', 'L', ':', 'P', '_', 0, + 0, 0, '\"', 0, '{', '+', 0, 0, 0, '\n', '\n', '}', 0, '|', 0, 0, + 0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0, + '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0 + }; +/* kb_modifier_status: + BIT | Description + ----+----------------------------------- + 0 | Left Shift + 1 | Right Shift + 2 | Left Alt + 3 | Right Alt + 4 | Left CTRL + 5 | Right CTRL + 6 | Fake Shift */ +byte kb_modifier_status; + +/* kb_modifier_status: + BIT | Description + ----+----------------------------------- + 0 | Gray + 1 | Break code + 2 | 0xE1 (pause/break) + 3 | Recieved first byte from pause/break */ +byte kb_prefix; + +/* kb_lights_status + BIT | Description + ----+----------------------------------- + 0 | SCROLLOCK + 1 | NUMLOCK + 2 | CAPSLOCK */ +byte kb_lights_status; +byte kb_scancode_set; + + +/*************************************** + * Set repeat rate/delay * + *************************************** + Values for inter-character delay (bits 4-0) + (characters per second; default is 10.9) + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + ----+----+----+----+----+----+----+----+---- + 0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0 + 8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0 + 16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0 + 24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0 + + Values for delay: + (miliseconds; default is 500) + 0 | 1 | 2 | 3 + -----+-----+-----+----- + 250 | 500 | 750 | 1000 + + ***************************************/ +void kb_set_repeat(byte rate, byte delay) +{ + if (rate>3 || delay>31) return; + + byte out = rate<<5 | delay; + while ((inportb(0x64)&2) != 0); + outportb(0x60, 0xF3); + while ((inportb(0x64)&2) != 0); + outportb(0x60, out); +} + + +/*************************************** + * Set keyboard LEDs * + *************************************** + +-----------+-------+-------+--------+ + | Bits 7-3 | Bit 2 | Bit 1 | Bit 0 | + | 0 | Caps | Num | Scroll | + |(reserved) | lock | lock | lock | + +-----------+-------+-------+--------+ + ***************************************/ +void kb_set_LEDs(byte status) +{ + while ((inportb (0x64)&2)!=0); + outportb (0x60, 0xED); + + while ((inportb (0x64)&2)!=0); + outportb (0x60, status); +} + +/*************************************** + * Set scancode set * + *************************************** + 0 Get current scancode set + 1 Set to scancode set 1 + 2 Set to scancode set 2 + 3 Set to scancode set 3 + ***************************************/ +void kb_set_scancodeset(byte set) +{ + //If ask for current scancode, tell kb handler what to expect + if (set==0) kb_scancode_set = 4; + + while ((inportb (0x64)&2)!=0); + outportb (0x60, 0xF0); + + while ((inportb (0x64)&2)!=0); + outportb (0x60, set); +} + + +void kb_waitin() +{ + int fail_safe=200000; + while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--; +} + +void kb_waitout() +{ + int fail_safe=200000; + while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--; +} \ No newline at end of file diff --git a/link.ld b/kernel/link.ld similarity index 100% rename from link.ld rename to kernel/link.ld diff --git a/loader.asm b/kernel/loader.asm similarity index 95% rename from loader.asm rename to kernel/loader.asm index c5488fc..eba57f1 100644 --- a/loader.asm +++ b/kernel/loader.asm @@ -442,8 +442,37 @@ irq_common_stub: add esp, 8 iret + +[global _read_cr0] +_read_cr0: + mov eax, cr0 + retn + +[global _write_cr0] +_write_cr0: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr0, eax + pop ebp + retn +[global _read_cr3] +_read_cr3: + mov eax, cr3 + retn +[global _write_cr3] +_write_cr3: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr3, eax + pop ebp + retn + + + SECTION .bss resb 8192 ; This reserves 8KBytes of memory here _sys_stack: \ No newline at end of file diff --git a/kernel/loader.o b/kernel/loader.o new file mode 100644 index 0000000000000000000000000000000000000000..9e620cd8b89ae85c8b39cd8bc6871e17115b8c4f GIT binary patch literal 2348 zcmb7_T})g>6vt=zZo9a}mO`b41>4#$wD(e~L>pb{vfaS46j-BHyezv*3j*uCyTmp= z_^oMcaUV=g>`Uo`p&FA$A8h;z5&NPsG@2$DKT>0f9TWAz7_B_u|ID1;T;r2Bob&(9 znS0L68RkN{FD+(@gnoiTJYTGFP>c9*rb!416NN(2`M2weg-hpY$TLi< z!-e@(9yfIl)vd(@g8+!%Q`@hpAR}Fs+yOFx?_eraHNmX@jh1+9=mD z)ytJk4H6&*>&pUX0yEx&J$9w%0!=MndN6P%jOXc$f^IL3ZZA!4FSokA zY;t?q?Dn$7?d3MNm#uCu+uUBZyS?mid)evs((LwfyW7hh|GSq!aCRDyd{QM?cK8}mWvAIur(5_1;n z!-3HIM`7j6&w(qMPlDGlzXo2<|y>wqI?DVybP`5?&FJ6I)8JG#oe@L1oXAY1g*BcWnGn{Y$AvYL&chEUC&%*E;p9Ym zEaM>P*zO>gPda%qK9tSoMJ&w@3(qFk+2o&iblFU!B{vJ?|sOMc6Y=*(NH|m zZ*_Jh_C>;;=>BkMU%1zbg(A`R|AsrdLXkdCxP5=Py|XV76S@54&{!sqy{Gfm@YrPT zuu$GqomgYpB)S{PIlGiMl&86z)1v%tMEwLV(KcUu43vcrmkY@DlNK7iy_d0mCBBfXD2K=1nktY zY0|N21;?fZ9GmJpHkEg5s_xiS+_9;)V^e9zrpn0TWSyI+ +#include +#include "clock/pictimer.c" +#include "keyboard/keyus.c" +#include "kernel/prologue.c" +#include "kernel/epilogue.c" +#include "shell/shell.c" + +int main() +{ + system_init(); + + shell(); + + // do nothing + for(;;); + return 0; +} \ No newline at end of file diff --git a/kernel/main.o b/kernel/main.o new file mode 100644 index 0000000000000000000000000000000000000000..c776921d2843056d58c73e8eb98bf7189c0c277e GIT binary patch literal 20986 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 z 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 literal 0 HcmV?d00001 diff --git a/kernel/shell/apps.h b/kernel/shell/apps.h new file mode 100644 index 0000000..cf2adb5 --- /dev/null +++ b/kernel/shell/apps.h @@ -0,0 +1,122 @@ +const char *apps_lst[] = { + "", + "reboot", + "osver", + "date", + "place", + "cls", + "memory" + }; +int apps_count = 7; + +void apps_osver() +{ + puts("CTA OS v0.1"); + puts("\n(c) CTA 2010.\n"); +} + +void apps_date() +{ + puts("Today is "); + puts((char*)clock_weekdays[clock.weekday]); + puts(", "); putc((clock.day/10)+'0'); + putc((clock.day%10)+'0'); + puts(" "); puts((char*)clock_months[clock.month]); + puts(" "); putc((clock.century/10)+'0'); + putc((clock.century%10)+'0'); + putc((clock.year/10)+'0'); + putc((clock.year%10)+'0'); + putc('\n'); +} + +void apps_place() +{ + puts("On your desk, if you didn't notice... \n"); +} + +void apps_clrscr() +{ + clrscr(); +} + +void apps_memory(const int pn, const char* param[]) +{ + if (pn<3) { + puts ("Correct syntax: memory [start_address] [end_address] (in hex)\n"); + return; + } + + byte *start, *end; + byte l1 = strlen(param[1]), l2 = strlen(param[2]); + unsigned int a; + int i; byte *count; + + a = 0; + for(i = 0; i < l1; i++) { + switch (param[1][i]) { + case 'a': + case 'A': a = a*16 + 10; break; + case 'b': + case 'B': a = a*16 + 11; break; + case 'c': + case 'C': a = a*16 + 12; break; + case 'd': + case 'D': a = a*16 + 13; break; + case 'e': + case 'E': a = a*16 + 14; break; + case 'f': + case 'F': a = a*16 + 15; break; + + default: if (!(param[1][i]>='0' && param[1][i]<='9')) { + puts ((char*)param[1]); puts(" is not a valid hex address.\n"); + return; + } + a = a*16 + (param[1][i] - '0'); + break; + } + } + start = (byte *)a; + + a = 0; + for(i = 0; i < l2; i++) { + switch (param[2][i]) { + case 'a': + case 'A': a = a*16 + 10; break; + case 'b': + case 'B': a = a*16 + 11; break; + case 'c': + case 'C': a = a*16 + 12; break; + case 'd': + case 'D': a = a*16 + 13; break; + case 'e': + case 'E': a = a*16 + 14; break; + case 'f': + case 'F': a = a*16 + 15; break; + + default: if (!(param[2][i]>='0' && param[2][i]<='9')) { + puts ((char*)param[2]); puts(" is not a valid hex address.\n"); + return; + } + a = a*16 + (param[2][i] - '0'); + break; + } + } + end = (byte *)a; + + while (start <= end) { + put_hex ((unsigned int) start); puts(": "); + + for (count = start; count < start+16; count++) { + putc(hex[*count/16]); putc(hex[*count%16]); + putc(' '); + } + puts(" "); + for (count = start; count < start+16; count++) + putc(*count); + + putc('\n'); + start+=16; + } + + +} \ No newline at end of file diff --git a/kernel/shell/shell.c b/kernel/shell/shell.c new file mode 100644 index 0000000..9f6220d --- /dev/null +++ b/kernel/shell/shell.c @@ -0,0 +1,81 @@ +#include +#include "apps.h" + +void get_str(char *str, int len) +{ + kb_key alpha; + + int i; + for (i = 0; i0) { // Only backspace our string + if (--cursor_x < 0) { // Begin of row - 1 = End of previous row + cursor_x = 79; cursor_y--; + } + putc_pos(cursor_x, cursor_y, 0); + str[--i] = 0; + } + i--; break; + + case '\n': str[i]=0; putc('\n'); return; + + default: putc(alpha.character); + str[i] = alpha.character; + str[i+1] = 0; + break; + } + } +} + + +void shell() +{ + char str[256]; + char* param[16]; + int i, len, params=0; + + set_default_colors (0x07, 0x04); + clrscr(); + + + + for (;;) { + puts("\n] "); + get_str(str, 256); + + len = strlen(str); + + // Ignore spaces in front of command + i=0; params = 0; + while (str[i] == ' ') i++; + param[params] = str+i; params++; i++; // Parameter 0 = app itself + + + for (; i < len && params<16; i++) { + if (str[i] == ' ') str[i]=0; + + if (str[i] != 0 && str[i-1]==0) { + param[params] = str+i; params++; + } + } + + for (i = 0; strcmp(apps_lst[i], param[0])!=0 && i */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, /* < ... F10 */ - 0, /* 69 - Num lock*/ - 0, /* Scroll Lock */ - 0, /* Home key */ - 0, /* Up Arrow */ - 0, /* Page Up */ - '-', - 0, /* Left Arrow */ - 0, - 0, /* Right Arrow */ - '+', - 0, /* 79 - End key*/ - 0, /* Down Arrow */ - 0, /* Page Down */ - 0, /* Insert Key */ - 0, /* Delete Key */ - 0, 0, 0, - 0, /* F11 Key */ - 0, /* F12 Key */ - 0, /* All other keys are undefined */ -}; - -unsigned char kbdus_shift[128] = -{ - 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */ - '(', ')', '_', '+', '\b', /* Backspace */ - '\t', /* Tab */ - 'Q', 'W', 'E', 'R', /* 19 */ - 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter key */ - 0, /* 29 - Control */ - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */ - '\"', '~', 0, /* Left shift */ - '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */ - 'M', '<', '>', '?', 0, /* Right shift */ - '*', - 0, /* Alt */ - ' ', /* Space bar */ - 0, /* Caps lock */ - 0, /* 59 - F1 key ... > */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, /* < ... F10 */ - 0, /* 69 - Num lock*/ - 0, /* Scroll Lock */ - 0, /* Home key */ - 0, /* Up Arrow */ - 0, /* Page Up */ - '-', - 0, /* Left Arrow */ - 0, - 0, /* Right Arrow */ - '+', - 0, /* 79 - End key*/ - 0, /* Down Arrow */ - 0, /* Page Down */ - 0, /* Insert Key */ - 0, /* Delete Key */ - 0, 0, 0, - 0, /* F11 Key */ - 0, /* F12 Key */ - 0, /* All other keys are undefined */ -}; - - - -/* kb_modifier_status: - BIT | Description - ----+----------------------------------- - 0 | Left Shift - 1 | Right Shift - 2 | Left Alt - 3 | Right Alt - 4 | Left CTRL - 5 | Right CTRL - 6 | Fake Shift - 7 | Special */ -unsigned char kb_modifier_status; - -/* kb_lights_status - BIT | Description - ----+----------------------------------- - 0 | SCROLLOCK - 1 | NUMLOCK - 2 | CAPSLOCK */ -unsigned char kb_lights_status; - -void kb_update_LED() -{ - while ((inportb (0x64)&2)!=0); - outportb (0x60, 0xED); - - while ((inportb (0x64)&2)!=0); - outportb (0x60, kb_lights_status); -} - -/* kb_toggle_LED - Toggle NUM/CAPS/SCROLL LOCK LEDs. 0 to ignore. If all 0, reset; */ -void kb_toggle_LED(int NUM, int CAPS, int SCROLL) -{ - if (NUM) kb_lights_status ^= 1<<1; - if (CAPS) kb_lights_status ^= 1<<2; - if (SCROLL) kb_lights_status ^= 1; - if ((!NUM) && (!CAPS) && (!SCROLL)) kb_lights_status = 0; - kb_update_LED(); -} - -byte prev, scancode; -void kb_handler(regs *r) { - scancode = inportb(0x60); - - puts_pos(0, 0, "Key Pressed ");put_hex(30, 0, scancode); - - switch (scancode) { - // Special - case 0x0E: kb_modifier_status |= 1<<7; - break; - - // Left Shift or fake shift make - case 0x2A: if (kb_modifier_status && 128) kb_modifier_status |= 1<<6; - else kb_modifier_status |= 1; - break; - - // Left Shift or fake shift release - case 0xAA: if (kb_modifier_status && 128) kb_modifier_status &= (1<<6) ^0xFF; - else kb_modifier_status &= 1 ^0xFF; - break; - - // Right Shift make - case 0x36: kb_modifier_status |= 1<<1; - break; - - // Right shift release - case 0xB6: kb_modifier_status &= (1<<1) ^0xFF; - break; - - // Left Alt or Right Alt make - case 0x38: if (kb_modifier_status && 128) kb_modifier_status |= 1<<3; - else kb_modifier_status |= 1<<2; - break; - - // Left Alt or Right Alt release - case 0xB8: if (kb_modifier_status && 128) kb_modifier_status &= (1<<3) ^0xFF; - else kb_modifier_status &= (1<<2) ^0xFF; - break; - - // Left Ctrl or Right Ctrl make - case 0x1D: if (kb_modifier_status && 128) kb_modifier_status |= 1<<5; - else kb_modifier_status |= 1<<4; - break; - - // Left Ctrl or Right Ctrl release - case 0x9D: if (kb_modifier_status && 128) kb_modifier_status &= (1<<5) ^0xFF; - else kb_modifier_status &= (1<<5) ^0xFF; - break; - - // Caps, Num and Scroll (in this order) - case 0x3A: kb_toggle_LED (0,1,0); break; - case 0x45: kb_toggle_LED (1,0,0); break; - case 0x46: kb_toggle_LED (0,0,1); break; - - default: if (scancode & 0x80) break; - if (scancode != prev) kb_modifier_status &= (1<<7) ^0xFF; - if ((kb_modifier_status && 1) || (kb_modifier_status && 2)) - putc_pos(50, 0, kbdus_shift[scancode]); - else putc_pos (50, 0, kbdus[scancode]); - break; - } - - outportb(0x20, 0x20); -} - - -char kb_getch() -{ - regs *r = 0; - do { - prev = scancode; kb_handler(r); } - while (prev == scancode || prev+0x80 == scancode); - - - if ((kb_modifier_status && 1) || (kb_modifier_status && 2)) - return kbdus_shift[scancode]; - - return kbdus[scancode]; -} - -void kb_get_status() -{ - byte a = inportb(0x64); - puts_pos(0, 8, "KeyBrd Status: "); - put_bin(0, 9, a); -} \ No newline at end of file diff --git a/loader.o b/loader.o deleted file mode 100644 index 273055864fdbfc3020c9fe3d5030b89eb1f801b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2226 zcmb7_U2GIp6vyvwKeoWur9x@3&<_OUtIA9%+9=VrY?n=UyQS?C1a;VUx6r!Xb!N5+ z#0R5BgGSaq7=7@C`d~z3Lf}E-SB%Ju#*}DCG@`)(k!zwp7^B#S^?&X?PR97;r04v9 zbMBn~oin?$4Fz)Icu?r0Q;4w|jfb>|500-BLL$W6T=4WeZ8ahw7SnsLg?ZgCHx{bZ zs$4{h1e$4K^4xM!`MUCPF5xC^d-lk-%D7Jpb3Um=|_ecRZKN9 z%v39bOm*^4G*d^t{DmnbuPJJfm$|Y;eyM1w{7mUG`H9l7d{1ekJfrj$`Ib^K9g!!Q zmdjU|n&gX2x5}rPR>-4FD`k~8l$pcI+a+s-A4lu2j_c7fjO{O-viD`{&XId*) zGPTR4OdS#+4z<@uPDbAJKiKE544c#z$Q<3>lNA{^t8*sirRzrOTUToj1$v z-Yo0ASvGjHZ1iTi!<%K3H_K*kmMz{aTfJGfd9!qTv)t*;a@YT!We%S{zB{6}6=~{XpKZla% zHpEv5+G{7`dj!?#-MfyU`Y7U8=7Z4Rne)&^<`Oi32SV2$Lxh;00XH(A0Iy(v6}*~x z9^AqFHh2T`S@2fo55Xq$1#lnp7vKk&FM;FC-+_miuY)tpG{?itH^CFkHPC5hx?h{Q z1$vaZ3;HB8-Pd!>z0ecP_d{Q1PC#E{9)-Tn{0Q_E^I_;|X4>;z<|m*ZF+U5vfS}Li zCFmutzYqPEnbv<`UV#3{{0;PH=Bv=(n5lM?`44E7Ie;%n9R>DU2BjcwhBh&GKwFtN zL+PBZ>49!!-UaPujzf1a?}grrpji$=2NCq^L;p7RfhS72ycl;~kuTGRd*TgX#2`H5`q{tY|V3AMzDb zu~d5GAuBO7koHxh>CBiln9S^s$9&a2vFPsDh?R=Q6aD`!4mCs*n`#oPP|9MuDc9MqvY|4qxlWJDJ5=sfd8f*Et9*~jeJUH= zth)`}Zs>kP8yMQb&=!XFFtmxGT} ziPFqWsc6wdz@0iaEjl*s;MlZ*W0SvQlf7e;yJM5NW0SXIleJ@$GrG80cdIE;)ctBo Uob?J^`0riaV=ng3PCO?52JEfXCIA2c diff --git a/main.c b/main.c deleted file mode 100644 index 84c99d2..0000000 --- a/main.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include "gdt.c" -#include "idt.c" -#include "isrs.c" -#include "irq.c" -#include "timer.c" -#include "keyus.c" -#include "init.c" - - -/*void put_line_scroll(int line, char c) -{ - int i = 0; - while (TextVideoRam[2*(80*line+i)] != 0 && i<=80) ++i; - if (i>78) { - memcpy(TextVideoRam + (2*80*line), TextVideoRam + (2*80*line) + 2, (i+1)*2); - } - putc_pos(i, line, c); -}*/ - - -int main() -{ - system_init(); - set_default_colors (0x07, 0x04); - clrscr(); - - int i; - for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F); - puts_pos_font (60, 0, "Uptime:", 0x02, 0x0E); cursor_y++; - - // Do other stuff - puts ("Testing puts...\nAnd this shoudl be new line\n"); - puts_font ("And this should be colored in another color ", 0x02, 0x0F); - puts ("<- colored font should be right about heree"); - - puts_pos (0, 23, "This text should be starting in position (0, 23)"); - puts_pos_font (0, 23, "THIS", 0x00, 0x09); - - puts_pos (5, 20, "<- The cursor should be blinking right here"); - putc_pos_font (3, 20, 0, 0x04, 0x0F); - text_mode_cursor(3, 20); - - - while (1) { - kb_get_status(); - - put_bin(60, 15, kb_modifier_status); - puts_pos_font (60, 16, "LShift", 0x07, 0x08 - (kb_modifier_status&1)*0x06); - puts_pos_font (60, 17, "RShift", 0x07, 0x08 - (kb_modifier_status&2)*0x06); - puts_pos_font (60, 18, "LAlt", 0x07, 0x08 - (kb_modifier_status&4)*0x06); - puts_pos_font (60, 19, "RAlt", 0x07, 0x08 - (kb_modifier_status&8)*0x06); - puts_pos_font (60, 20, "LCtrl", 0x07, 0x08 - (kb_modifier_status&16)*0x06); - puts_pos_font (60, 21, "RCtrl", 0x07, 0x08 - (kb_modifier_status&32)*0x06); - puts_pos_font (60, 22, "FakeShift", 0x07, 0x08 - (kb_modifier_status&64)*0x06); - puts_pos_font (60, 23, "Special", 0x07, 0x08 - (kb_modifier_status&128)*0x06); - - putc (kb_getch()); - } - - // do nothing - for(;;); - return 0; -} \ No newline at end of file diff --git a/main.o b/main.o deleted file mode 100644 index 5f8a70a7c92fd8760df3ce0d3a328e44d42cbbee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12679 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 diff --git a/stage1/MAKE.PIF b/stage1/MAKE.PIF new file mode 100644 index 0000000000000000000000000000000000000000..e4ad68871e7d1b760f156ba14d1263d8da361f60 GIT binary patch literal 967 zcmZRm@OAWdWxxp3wGtzw)*9Q}i1RPu|`6Z0~QQ&VDsLmb^*4P!u>^_(0-aOxi% z5{wN0B?A~3*av}Yd_A3m{Db}7LKFf#-CQFW+8G%b3K_#a{apORgB6S|%oL3E3>a9M z<}zk5fC4{-!HD7ie+DpS5@2GGr-2_}wukxpDwqIm|Nmc_X${a_v;jbW`??3|x%l`{ z%Y0xk!GRG2vco}aRt8B1W`+|CFPNDaxZtufP#x?HJPaYJMY)-Ii8*jX&=@|Y$(bpM z3eNd?#rZj@Xp&$qGms1b+GD_^!)U{l&L{@t0}~w-@aMGkS)f@0073} BJ^ugz literal 0 HcmV?d00001 diff --git a/stage1/bootload.asm b/stage1/bootload.asm new file mode 100644 index 0000000..9769325 --- /dev/null +++ b/stage1/bootload.asm @@ -0,0 +1,314 @@ + +;********************************************* +; Boot1.asm +; - A Simple Bootloader +; +; Operating Systems Development Series +;********************************************* + +bits 16 ; we are in 16 bit real mode + +org 0 ; we will set regisers later + +start: jmp main ; jump to start of bootloader + +;********************************************* +; BIOS Parameter Block +;********************************************* + +; BPB Begins 3 bytes from start. We do a far jump, which is 3 bytes in size. +; If you use a short jump, add a "nop" after it to offset the 3rd byte. + +bpbOEM db "CTA OS " ; OEM identifier (Cannot exceed 8 bytes!) +bpbBytesPerSector: DW 512 +bpbSectorsPerCluster: DB 1 +bpbReservedSectors: DW 1 +bpbNumberOfFATs: DB 2 +bpbRootEntries: DW 224 +bpbTotalSectors: DW 2880 +bpbMedia: DB 0xf8 ;; 0xF1 +bpbSectorsPerFAT: DW 9 +bpbSectorsPerTrack: DW 18 +bpbHeadsPerCylinder: DW 2 +bpbHiddenSectors: DD 0 +bpbTotalSectorsBig: DD 0 +bsDriveNumber: DB 0 +bsUnused: DB 0 +bsExtBootSignature: DB 0x29 +bsSerialNumber: DD 0xa0a1a2a3 +bsVolumeLabel: DB "CTA FLOPPY " +bsFileSystem: DB "FAT12 " + +;************************************************; +; Prints a string +; DS=>SI: 0 terminated string +;************************************************; +Print: + lodsb ; load next byte from string from SI to AL + or al, al ; Does AL=0? + jz PrintDone ; Yep, null terminator found-bail out + mov ah, 0eh ; Nope-Print the character + int 10h + jmp Print ; Repeat until null terminator found + PrintDone: + ret ; we are done, so return + +;************************************************; +; Reads a series of sectors +; CX=>Number of sectors to read +; AX=>Starting sector +; ES:BX=>Buffer to read to +;************************************************; + +ReadSectors: + .MAIN: + mov di, 0x0005 ; five retries for error + .SECTORLOOP: + push ax + push bx + push cx + call LBACHS ; convert starting sector to CHS + mov ah, 0x02 ; BIOS read sector + mov al, 0x01 ; read one sector + mov ch, BYTE [absoluteTrack] ; track + mov cl, BYTE [absoluteSector] ; sector + mov dh, BYTE [absoluteHead] ; head + mov dl, BYTE [bsDriveNumber] ; drive + int 0x13 ; invoke BIOS + jnc .SUCCESS ; test for read error + xor ax, ax ; BIOS reset disk + int 0x13 ; invoke BIOS + dec di ; decrement error counter + pop cx + pop bx + pop ax + jnz .SECTORLOOP ; attempt to read again + int 0x18 + .SUCCESS: + mov si, msgProgress + call Print + pop cx + pop bx + pop ax + add bx, WORD [bpbBytesPerSector] ; queue next buffer + inc ax ; queue next sector + loop .MAIN ; read next sector + ret + +;************************************************; +; Convert CHS to LBA +; LBA = (cluster - 2) * sectors per cluster +;************************************************; + +ClusterLBA: + sub ax, 0x0002 ; zero base cluster number + xor cx, cx + mov cl, BYTE [bpbSectorsPerCluster] ; convert byte to word + mul cx + add ax, WORD [datasector] ; base data sector + ret + +;************************************************; +; Convert LBA to CHS +; AX=>LBA Address to convert +; +; absolute sector = (logical sector / sectors per track) + 1 +; absolute head = (logical sector / sectors per track) MOD number of heads +; absolute track = logical sector / (sectors per track * number of heads) +; +;************************************************; + +LBACHS: + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbSectorsPerTrack] ; calculate + inc dl ; adjust for sector 0 + mov BYTE [absoluteSector], dl + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbHeadsPerCylinder] ; calculate + mov BYTE [absoluteHead], dl + mov BYTE [absoluteTrack], al + ret + +;********************************************* +; Bootloader Entry Point +;********************************************* + +main: + + ;---------------------------------------------------- + ; code located at 0000:7C00, adjust segment registers + ;---------------------------------------------------- + + cli ; disable interrupts + mov ax, 0x07C0 ; setup registers to point to our segment + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ;---------------------------------------------------- + ; create stack + ;---------------------------------------------------- + + mov ax, 0x0000 ; set the stack + mov ss, ax + mov sp, 0xFFFF + sti ; restore interrupts + + ;---------------------------------------------------- + ; Display loading message + ;---------------------------------------------------- + + mov si, msgLoading + call Print + + ;---------------------------------------------------- + ; Load root directory table + ;---------------------------------------------------- + + LOAD_ROOT: + + ; compute size of root directory and store in "cx" + + xor cx, cx + xor dx, dx + mov ax, 0x0020 ; 32 byte directory entry + mul WORD [bpbRootEntries] ; total size of directory + div WORD [bpbBytesPerSector] ; sectors used by directory + xchg ax, cx + + ; compute location of root directory and store in "ax" + + mov al, BYTE [bpbNumberOfFATs] ; number of FATs + mul WORD [bpbSectorsPerFAT] ; sectors used by FATs + add ax, WORD [bpbReservedSectors] ; adjust for bootsector + mov WORD [datasector], ax ; base of root directory + add WORD [datasector], cx + + ; read root directory into memory (7C00:0200) + + mov bx, 0x0200 ; copy root dir above bootcode + call ReadSectors + + ;---------------------------------------------------- + ; Find stage 2 + ;---------------------------------------------------- + + ; browse root directory for binary image + mov cx, WORD [bpbRootEntries] ; load loop counter + mov di, 0x0200 ; locate first root entry + .LOOP: + push cx + mov cx, 0x000B ; eleven character name + mov si, ImageName ; image name to find + push di + rep cmpsb ; test for entry match + pop di + je LOAD_FAT + pop cx + add di, 0x0020 ; queue next directory entry + loop .LOOP + jmp FAILURE + + ;---------------------------------------------------- + ; Load FAT + ;---------------------------------------------------- + + LOAD_FAT: + + ; save starting cluster of boot image + + mov dx, WORD [di + 0x001A] + mov WORD [cluster], dx ; file's first cluster + + ; compute size of FAT and store in "cx" + + xor ax, ax + mov al, BYTE [bpbNumberOfFATs] ; number of FATs + mul WORD [bpbSectorsPerFAT] ; sectors used by FATs + mov cx, ax + + ; compute location of FAT and store in "ax" + + mov ax, WORD [bpbReservedSectors] ; adjust for bootsector + + ; read FAT into memory (7C00:0200) + + mov bx, 0x0200 ; copy FAT above bootcode + call ReadSectors + + ; read image file into memory (0050:0000) + + mov ax, 0x0050 + mov es, ax ; destination for image + mov bx, 0x0000 ; destination for image + push bx + + ;---------------------------------------------------- + ; Load Stage 2 + ;---------------------------------------------------- + + LOAD_IMAGE: + + mov ax, WORD [cluster] ; cluster to read + pop bx ; buffer to read into + call ClusterLBA ; convert cluster to LBA + xor cx, cx + mov cl, BYTE [bpbSectorsPerCluster] ; sectors to read + call ReadSectors + push bx + + ; compute next cluster + + mov ax, WORD [cluster] ; identify current cluster + mov cx, ax ; copy current cluster + mov dx, ax ; copy current cluster + shr dx, 0x0001 ; divide by two + add cx, dx ; sum for (3/2) + mov bx, 0x0200 ; location of FAT in memory + add bx, cx ; index into FAT + mov dx, WORD [bx] ; read two bytes from FAT + test ax, 0x0001 + jnz .ODD_CLUSTER + + .EVEN_CLUSTER: + + and dx, 0000111111111111b ; take low twelve bits + jmp .DONE + + .ODD_CLUSTER: + + shr dx, 0x0004 ; take high twelve bits + + .DONE: + + mov WORD [cluster], dx ; store new cluster + cmp dx, 0x0FF0 ; test for end of file + jb LOAD_IMAGE + + DONE: + push WORD 0x0050 + push WORD 0x0000 + retf + + FAILURE: + + mov si, msgFailure + call Print + mov ah, 0x00 + int 0x16 ; await keypress + int 0x19 ; warm boot computer + + absoluteSector db 0x00 + absoluteHead db 0x00 + absoluteTrack db 0x00 + + datasector dw 0x0000 + cluster dw 0x0000 + ImageName db "STAGE2 CTA" + msgLoading db 0x0D, "CTA OS v0.1", 0x0A, 0x0D, "(c) CTA 2010", 0x0A, 0x0D, "Loading", 0x00 + msgProgress db ".", 0x00 + msgFailure db 0x0D, 0x0A, "Error: Could not find stage2.bin. Press any key to reboot.", 0x0A, 0x00 + + TIMES 510-($-$$) db 0 + DW 0xAA55 diff --git a/stage1/bootload.bin b/stage1/bootload.bin new file mode 100644 index 0000000000000000000000000000000000000000..a1ea4682e05c7c9ec288c0ef6aecf05a3823ce2b GIT binary patch literal 512 zcmYLGL1@!p7=3@LtEM*F9K<<9{)31+7@8h>@U${IK?coeiVQYtu!LF#>L<9cNGJ@E|BuCM+gU@H@Tl@!t1+yl=3B`E;BnQOcZk_0{I??$%u%{~5MAM#1W|yB-PweT=9&t?9YXY}JnCn~CeFoxz&V@1j9vIV! zB_0oB)415L^XtUNGpO@*vZWF0yln=J6T>u44W|tl-#)wU-_Bd&ymG|@@wiPfygP|u zEQB|k6CUOf7~`<56T<0a7mSl}8{8ziV3t0G&@ss4U+to7aTK>)q8 zOa92(`Ok6X%c_J`;IPvr&fY}}HgDe?MV(5=A11tDy{N;Zx4e!BA{)Nc{m&!#52(t-Ak(CE@Uar2()3U76=cRI; OmBNZFs{#vTKKuj2jJ7KP literal 0 HcmV?d00001 diff --git a/stage1/make.bat b/stage1/make.bat new file mode 100644 index 0000000..05cd83b --- /dev/null +++ b/stage1/make.bat @@ -0,0 +1,18 @@ +@echo off +set nasm_path=C:\nasm +set djgpp_path=C:\DJGPP\bin +set drive=0 + +@echo on +%nasm_path%\nasm.exe -f bin bootload.asm -o bootload.bin + +@echo. +@echo Press any key to copy to (fd%drive%), or CTRL+C to stop. +@pause >nul + +@echo off +@echo w 100 %drive% 0 1 >f.tmp +@echo q>>f.tmp + +debug bootload.bin nul + +@echo off +copy stage2.cta A:\stage2.cta \ No newline at end of file diff --git a/stage2/a20.inc b/stage2/a20.inc new file mode 100644 index 0000000..f50e445 --- /dev/null +++ b/stage2/a20.inc @@ -0,0 +1,103 @@ + +;******************************************** +; Enable A20 address line +; +; OS Development Series +;******************************************** + +%ifndef __A20_INC_67343546FDCC56AAB872_INCLUDED__ +%define __A20_INC_67343546FDCC56AAB872_INCLUDED__ + +bits 16 + +;---------------------------------------------- +; Enables a20 line through keyboard controller +;---------------------------------------------- + +EnableA20_KKbrd: + + cli + push ax + mov al, 0xdd ; send enable a20 address line command to controller + out 0x64, al + pop ax + ret + +;-------------------------------------------- +; Enables a20 line through output port +;-------------------------------------------- + +EnableA20_KKbrd_Out: + + cli + pusha + + call wait_input + mov al,0xAD + out 0x64,al ; disable keyboard + call wait_input + + mov al,0xD0 + out 0x64,al ; tell controller to read output port + call wait_output + + in al,0x60 + push eax ; get output port data and store it + call wait_input + + mov al,0xD1 + out 0x64,al ; tell controller to write output port + call wait_input + + pop eax + or al,2 ; set bit 1 (enable a20) + out 0x60,al ; write out data back to the output port + + call wait_input + mov al,0xAE ; enable keyboard + out 0x64,al + + call wait_input + popa + sti + ret + + ; wait for input buffer to be clear + +wait_input: + in al,0x64 + test al,2 + jnz wait_input + ret + + ; wait for output buffer to be clear + +wait_output: + in al,0x64 + test al,1 + jz wait_output + ret + +;-------------------------------------- +; Enables a20 line through bios +;-------------------------------------- + +EnableA20_Bios: + pusha + mov ax, 0x2401 + int 0x15 + popa + ret + +;------------------------------------------------- +; Enables a20 line through system control port A +;------------------------------------------------- + +EnableA20_SysControlA: + push ax + mov al, 2 + out 0x92, al + pop ax + ret + +%endif diff --git a/stage2/common.inc b/stage2/common.inc new file mode 100644 index 0000000..38bfda0 --- /dev/null +++ b/stage2/common.inc @@ -0,0 +1,17 @@ + +%ifndef _COMMON_INC_INCLUDED +%define _COMMON_INC_INCLUDED + +; where the kernel is to be loaded to in protected mode +%define IMAGE_PMODE_BASE 0x100000 + +; where the kernel is to be loaded to in real mode +%define IMAGE_RMODE_BASE 0x3000 + +; kernel name (Must be 11 bytes) +ImageName db "KERNEL CTA" + +; size of kernel image in bytes +ImageSize db 0 + +%endif diff --git a/stage2/fat12.inc b/stage2/fat12.inc new file mode 100644 index 0000000..f2a120b --- /dev/null +++ b/stage2/fat12.inc @@ -0,0 +1,243 @@ + +;******************************************************* +; +; Fat12.inc +; FAT12 filesystem for 3-1/2 floppies +; +; OS Development Series +;******************************************************* + +%ifndef __FAT12_INC_67343546FDCC56AAB872_INCLUDED__ +%define __FAT12_INC_67343546FDCC56AAB872_INCLUDED__ + +bits 16 + +%include "Floppy16.inc" ; the erm.. floppy driver + +%define ROOT_OFFSET 0x2e00 +%define FAT_SEG 0x2c0 +%define ROOT_SEG 0x2e0 + +;******************************************* +; LoadRoot () +; - Load Root Directory Table to 0x7e00 +;******************************************* + +LoadRoot: + + pusha ; store registers + push es + + ; compute size of root directory and store in "cx" + + xor cx, cx ; clear registers + xor dx, dx + mov ax, 32 ; 32 byte directory entry + mul WORD [bpbRootEntries] ; total size of directory + div WORD [bpbBytesPerSector] ; sectors used by directory + xchg ax, cx ; move into AX + + ; compute location of root directory and store in "ax" + + mov al, BYTE [bpbNumberOfFATs] ; number of FATs + mul WORD [bpbSectorsPerFAT] ; sectors used by FATs + add ax, WORD [bpbReservedSectors] + mov WORD [datasector], ax ; base of root directory + add WORD [datasector], cx + + ; read root directory into 0x7e00 + + push word ROOT_SEG + pop es + mov bx, 0 ; copy root dir + call ReadSectors ; read in directory table + pop es + popa ; restore registers and return + ret + +;******************************************* +; LoadFAT () +; - Loads FAT table to 0x7c00 +; +; Parm/ ES:DI => Root Directory Table +;******************************************* + +LoadFAT: + + pusha ; store registers + push es + + ; compute size of FAT and store in "cx" + + xor ax, ax + mov al, BYTE [bpbNumberOfFATs] ; number of FATs + mul WORD [bpbSectorsPerFAT] ; sectors used by FATs + mov cx, ax + + ; compute location of FAT and store in "ax" + + mov ax, WORD [bpbReservedSectors] + + ; read FAT into memory (Overwrite our bootloader at 0x7c00) + + push word FAT_SEG + pop es + xor bx, bx + call ReadSectors + pop es + popa ; restore registers and return + ret + +;******************************************* +; FindFile () +; - Search for filename in root table +; +; parm/ DS:SI => File name +; ret/ AX => File index number in directory table. -1 if error +;******************************************* + +FindFile: + + push cx ; store registers + push dx + push bx + mov bx, si ; copy filename for later + + ; browse root directory for binary image + + mov cx, WORD [bpbRootEntries] ; load loop counter + mov di, ROOT_OFFSET ; locate first root entry at 1 MB mark + cld ; clear direction flag + +.LOOP: + push cx + mov cx, 11 ; eleven character name. Image name is in SI + mov si, bx ; image name is in BX + push di + rep cmpsb ; test for entry match + pop di + je .Found + pop cx + add di, 32 ; queue next directory entry + loop .LOOP + +.NotFound: + pop bx ; restore registers and return + pop dx + pop cx + mov ax, -1 ; set error code + ret + +.Found: + pop ax ; return value into AX contains entry of file + pop bx ; restore registers and return + pop dx + pop cx + ret + +;******************************************* +; LoadFile () +; - Load file +; parm/ ES:SI => File to load +; parm/ EBX:BP => Buffer to load file to +; ret/ AX => -1 on error, 0 on success +; ret/ CX => number of sectors read +;******************************************* + +LoadFile: + + xor ecx, ecx ; size of file in sectors + push ecx + +.FIND_FILE: + + push bx ; BX=>BP points to buffer to write to; store it for later + push bp + call FindFile ; find our file. ES:SI contains our filename + cmp ax, -1 + jne .LOAD_IMAGE_PRE + pop bp + pop bx + pop ecx + mov ax, -1 + ret + +.LOAD_IMAGE_PRE: + + sub edi, ROOT_OFFSET + sub eax, ROOT_OFFSET + + ; get starting cluster + + push word ROOT_SEG ;root segment loc + pop es + mov dx, WORD [es:di + 0x001A]; DI points to file entry in root directory table. Refrence the table... + mov WORD [cluster], dx ; file's first cluster + pop bx ; get location to write to so we dont screw up the stack + pop es + push bx ; store location for later again + push es + call LoadFAT + +.LOAD_IMAGE: + + ; load the cluster + + mov ax, WORD [cluster] ; cluster to read + pop es ; bx:bp=es:bx + pop bx + call ClusterLBA + xor cx, cx + mov cl, BYTE [bpbSectorsPerCluster] + call ReadSectors + pop ecx + inc ecx ; add one more sector to counter + push ecx + push bx + push es + mov ax, FAT_SEG ;start reading from fat + mov es, ax + xor bx, bx + + ; get next cluster + + mov ax, WORD [cluster] ; identify current cluster + mov cx, ax ; copy current cluster + mov dx, ax + shr dx, 0x0001 ; divide by two + add cx, dx ; sum for (3/2) + + mov bx, 0 ;location of fat in memory + add bx, cx + mov dx, WORD [es:bx] + test ax, 0x0001 ; test for odd or even cluster + jnz .ODD_CLUSTER + +.EVEN_CLUSTER: + + and dx, 0000111111111111b ; take low 12 bits + jmp .DONE + +.ODD_CLUSTER: + + shr dx, 0x0004 ; take high 12 bits + +.DONE: + + mov WORD [cluster], dx + cmp dx, 0x0ff0 ; test for end of file marker + jb .LOAD_IMAGE + +.SUCCESS: + pop es + pop bx + pop ecx + xor ax, ax + ret + +%endif ;__FAT12_INC_67343546FDCC56AAB872_INCLUDED__ + + + + + diff --git a/stage2/floppy16.inc b/stage2/floppy16.inc new file mode 100644 index 0000000..5893a6a --- /dev/null +++ b/stage2/floppy16.inc @@ -0,0 +1,117 @@ + +;******************************************************* +; +; Floppy16.inc +; Floppy drive interface routines +; +; OS Development Series +;******************************************************* + +%ifndef __FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__ +%define __FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__ + +bits 16 + +bpbOEM db "My OS " +bpbBytesPerSector: DW 512 +bpbSectorsPerCluster: DB 1 +bpbReservedSectors: DW 1 +bpbNumberOfFATs: DB 2 +bpbRootEntries: DW 224 +bpbTotalSectors: DW 2880 +bpbMedia: DB 0xf0 ;; 0xF1 +bpbSectorsPerFAT: DW 9 +bpbSectorsPerTrack: DW 18 +bpbHeadsPerCylinder: DW 2 +bpbHiddenSectors: DD 0 +bpbTotalSectorsBig: DD 0 +bsDriveNumber: DB 0 +bsUnused: DB 0 +bsExtBootSignature: DB 0x29 +bsSerialNumber: DD 0xa0a1a2a3 +bsVolumeLabel: DB "MOS FLOPPY " +bsFileSystem: DB "FAT12 " + +datasector dw 0x0000 +cluster dw 0x0000 + +absoluteSector db 0x00 +absoluteHead db 0x00 +absoluteTrack db 0x00 + +;************************************************; +; Convert CHS to LBA +; LBA = (cluster - 2) * sectors per cluster +;************************************************; + +ClusterLBA: + sub ax, 0x0002 ; zero base cluster number + xor cx, cx + mov cl, BYTE [bpbSectorsPerCluster] ; convert byte to word + mul cx + add ax, WORD [datasector] ; base data sector + ret + +;************************************************; +; Convert LBA to CHS +; AX=>LBA Address to convert +; +; absolute sector = (logical sector / sectors per track) + 1 +; absolute head = (logical sector / sectors per track) MOD number of heads +; absolute track = logical sector / (sectors per track * number of heads) +; +;************************************************; + +LBACHS: + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbSectorsPerTrack] ; calculate + inc dl ; adjust for sector 0 + mov BYTE [absoluteSector], dl + xor dx, dx ; prepare dx:ax for operation + div WORD [bpbHeadsPerCylinder] ; calculate + mov BYTE [absoluteHead], dl + mov BYTE [absoluteTrack], al + ret + + +;************************************************; +; Reads a series of sectors +; CX=>Number of sectors to read +; AX=>Starting sector +; ES:EBX=>Buffer to read to +;************************************************; + +ReadSectors: + .MAIN: + mov di, 0x0005 ; five retries for error + .SECTORLOOP: + push ax + push bx + push cx + call LBACHS ; convert starting sector to CHS + mov ah, 0x02 ; BIOS read sector + mov al, 0x01 ; read one sector + mov ch, BYTE [absoluteTrack] ; track + mov cl, BYTE [absoluteSector] ; sector + mov dh, BYTE [absoluteHead] ; head + mov dl, BYTE [bsDriveNumber] ; drive + int 0x13 ; invoke BIOS + jnc .SUCCESS ; test for read error + xor ax, ax ; BIOS reset disk + int 0x13 ; invoke BIOS + dec di ; decrement error counter + pop cx + pop bx + pop ax + jnz .SECTORLOOP ; attempt to read again + int 0x18 + .SUCCESS: + pop cx + pop bx + pop ax + add bx, WORD [bpbBytesPerSector] ; queue next buffer + inc ax ; queue next sector + loop .MAIN ; read next sector + ret + +%endif ;__FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__ diff --git a/stage2/gdt.inc b/stage2/gdt.inc new file mode 100644 index 0000000..952d66f --- /dev/null +++ b/stage2/gdt.inc @@ -0,0 +1,68 @@ + + +;************************************************* +; Gdt.inc +; -GDT Routines +; +; OS Development Series +;************************************************* + +%ifndef __GDT_INC_67343546FDCC56AAB872_INCLUDED__ +%define __GDT_INC_67343546FDCC56AAB872_INCLUDED__ + +bits 16 + +;******************************************* +; InstallGDT() +; - Install our GDT +;******************************************* + +InstallGDT: + + cli ; clear interrupts + pusha ; save registers + lgdt [toc] ; load GDT into GDTR + sti ; enable interrupts + popa ; restore registers + ret ; All done! + +;******************************************* +; Global Descriptor Table (GDT) +;******************************************* + +gdt_data: + dd 0 ; null descriptor + dd 0 + +; gdt code: ; code descriptor + dw 0FFFFh ; limit low + dw 0 ; base low + db 0 ; base middle + db 10011010b ; access + db 11001111b ; granularity + db 0 ; base high + +; gdt data: ; data descriptor + dw 0FFFFh ; limit low (Same as code)10:56 AM 7/8/2007 + dw 0 ; base low + db 0 ; base middle + db 10010010b ; access + db 11001111b ; granularity + db 0 ; base high + +end_of_gdt: +toc: + dw end_of_gdt - gdt_data - 1 ; limit (Size of GDT) + dd gdt_data ; base of GDT + +; give the descriptor offsets names + +%define NULL_DESC 0 +%define CODE_DESC 0x8 +%define DATA_DESC 0x10 + +%endif ;__GDT_INC_67343546FDCC56AAB872_INCLUDED__ + + + + diff --git a/stage2/stage2.asm b/stage2/stage2.asm new file mode 100644 index 0000000..1ead0de --- /dev/null +++ b/stage2/stage2.asm @@ -0,0 +1,158 @@ + +;******************************************************* +; +; Stage2.asm +; Stage2 Bootloader +; +; OS Development Series +;******************************************************* + +bits 16 + +; Remember the memory map-- 0x500 through 0x7bff is unused above the BIOS data area. +; We are loaded at 0x500 (0x50:0) + +org 0x500 + +jmp main ; go to start + +;******************************************************* +; Preprocessor directives +;******************************************************* + +%include "stdio.inc" ; basic i/o routines +%include "Gdt.inc" ; Gdt routines +%include "A20.inc" ; A20 enabling +%include "Fat12.inc" ; FAT12 driver. Kinda :) +%include "common.inc" + +;******************************************************* +; Data Section +;******************************************************* + +msgFailure db 0x0A, 0x0D, "FATAL ERROR: MISSING OR CORRUPT KERNEL.CTA", 0x0A, 0x0D, "Press any key to reboot...", 0x0D, 0x0A, 0x00 + +;******************************************************* +; STAGE 2 ENTRY POINT +; +; -Store BIOS information +; -Load Kernel +; -Install GDT; go into protected mode (pmode) +; -Jump to Stage 3 +;******************************************************* + +main: + + ;-------------------------------; + ; Setup segments and stack ; + ;-------------------------------; + + cli ; clear interrupts + xor ax, ax ; null segments + mov ds, ax + mov es, ax + mov ax, 0x0 ; stack begins at 0x9000-0xffff + mov ss, ax + mov sp, 0xFFFF + sti ; enable interrupts + + ;-------------------------------; + ; Install our GDT ; + ;-------------------------------; + + call InstallGDT ; install our GDT + + ;-------------------------------; + ; Enable A20 ; + ;-------------------------------; + + call EnableA20_KKbrd_Out + + ;-------------------------------; + ; Initialize filesystem ; + ;-------------------------------; + + call LoadRoot ; Load root directory table + + ;-------------------------------; + ; Load Kernel ; + ;-------------------------------; + + mov ebx, 0 ; BX:BP points to buffer to load to + mov bp, IMAGE_RMODE_BASE + mov si, ImageName ; our file to load + call LoadFile ; load our file + mov dword [ImageSize], ecx ; save size of kernel + cmp ax, 0 ; Test for success + je EnterStage3 ; yep--onto Stage 3! + mov si, msgFailure ; Nope--print error + call Puts16 + mov ah, 0 + int 0x16 ; await keypress + int 0x19 ; warm boot computer + cli ; If we get here, something really went wong + hlt + + ;-------------------------------; + ; Go into pmode ; + ;-------------------------------; + +EnterStage3: + + cli ; clear interrupts + mov eax, cr0 ; set bit 0 in cr0--enter pmode + or eax, 1 + mov cr0, eax + + jmp CODE_DESC:Stage3 ; far jump to fix CS. Remember that the code selector is 0x8! + + ; Note: Do NOT re-enable interrupts! Doing so will triple fault! + ; We will fix this in Stage 3. + +;****************************************************** +; ENTRY POINT FOR STAGE 3 +;****************************************************** + +bits 32 + +Stage3: + + ;-------------------------------; + ; Set registers ; + ;-------------------------------; + + mov ax, DATA_DESC ; set data segments to data selector (0x10) + mov ds, ax + mov ss, ax + mov es, ax + mov esp, 90000h ; stack begins from 90000h + + ;-------------------------------; + ; Copy kernel to 1MB ; + ;-------------------------------; + +CopyImage: + mov eax, dword [ImageSize] + movzx ebx, word [bpbBytesPerSector] + mul ebx + mov ebx, 4 + div ebx + cld + mov esi, IMAGE_RMODE_BASE + mov edi, IMAGE_PMODE_BASE + mov ecx, eax + rep movsd ; copy image to its protected mode address + + ;---------------------------------------; + ; Execute Kernel ; + ;---------------------------------------; + + jmp CODE_DESC:IMAGE_PMODE_BASE; jump to our kernel! Note: This assumes Kernel's entry point is at 1 MB + + ;---------------------------------------; + ; Stop execution ; + ;---------------------------------------; + + cli + hlt + diff --git a/stage2/stage2.cta b/stage2/stage2.cta new file mode 100644 index 0000000000000000000000000000000000000000..128a53cdc48346578c488083939ff6dcb7ea94ef GIT binary patch literal 1012 zcmXw2Z%7+w7=P|k-#cTIh_bjjy1k4|)(_2k`{0Lxv{Gy-)8NK()YX?=ko4Sdu7jxY5>wI%(Q`^E@uHC+t~tOY>C+pia)XcZiSiOgd%f$ zrsj-yq<;VT7?Hc`EjC$kQTeS#2=x}bEUHPtv*|ZyY7lSJuUM9KsCogDOwVi=$79}(WSOPY3s1)-RBPa$K= zfpSO_?i;;dp!&^}_bRgEuTaXnh~}4&w%P(>a9DqAw}r9@tvi=p!>%L$M4FKuo(5R|L4?u%#@eEY-8Z6N>gQT58%xI3J@ zjbZz*$j9M=WoaRb8WD|H<+E{OD` zHMfAch+eKYuSMr95+?n$5h|!`Mim}WUS5-LZtO4{bYx%VGpTZozf literal 0 HcmV?d00001 diff --git a/stage2/stdio.inc b/stage2/stdio.inc new file mode 100644 index 0000000..b1aa7d4 --- /dev/null +++ b/stage2/stdio.inc @@ -0,0 +1,298 @@ + +;************************************************* +; stdio.inc +; -Input/Output routines +; +; OS Development Series +;************************************************* + +%ifndef __STDIO_INC_67343546FDCC56AAB872_INCLUDED__ +%define __STDIO_INC_67343546FDCC56AAB872_INCLUDED__ + + +;========================================================== +; +; 16 Bit Real Mode Routines +;========================================================== + + +;************************************************; +; Puts16 () +; -Prints a null terminated string +; DS=>SI: 0 terminated string +;************************************************; + +bits 16 + +Puts16: + pusha ; save registers +.Loop1: + lodsb ; load next byte from string from SI to AL + or al, al ; Does AL=0? + jz Puts16Done ; Yep, null terminator found-bail out + mov ah, 0eh ; Nope-Print the character + int 10h ; invoke BIOS + jmp .Loop1 ; Repeat until null terminator found +Puts16Done: + popa ; restore registers + ret ; we are done, so return + + +;========================================================== +; +; 32 Bit Protected Mode Routines +;========================================================== + +bits 32 + +%define VIDMEM 0xB8000 ; video memory +%define COLS 80 ; width and height of screen +%define LINES 25 +%define CHAR_ATTRIB 63 ; character attribute (White text on light blue background) + +_CurX db 0 ; current x/y location +_CurY db 0 + +;**************************************************; +; Putch32 () +; - Prints a character to screen +; BL => Character to print +;**************************************************; + +Putch32: + + pusha ; save registers + mov edi, VIDMEM ; get pointer to video memory + + ;-------------------------------; + ; Get current position ; + ;-------------------------------; + + xor eax, eax ; clear eax + + ;-------------------------------- + ; Remember: currentPos = x + y * COLS! x and y are in _CurX and _CurY. + ; Because there are two bytes per character, COLS=number of characters in a line. + ; We have to multiply this by 2 to get number of bytes per line. This is the screen width, + ; so multiply screen with * _CurY to get current line + ;-------------------------------- + + mov ecx, COLS*2 ; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line + mov al, byte [_CurY] ; get y pos + mul ecx ; multiply y*COLS + push eax ; save eax--the multiplication + + ;-------------------------------- + ; Now y * screen width is in eax. Now, just add _CurX. But, again remember that _CurX is relative + ; to the current character count, not byte count. Because there are two bytes per character, we + ; have to multiply _CurX by 2 first, then add it to our screen width * y. + ;-------------------------------- + + mov al, byte [_CurX] ; multiply _CurX by 2 because it is 2 bytes per char + mov cl, 2 + mul cl + pop ecx ; pop y*COLS result + add eax, ecx + + ;------------------------------- + ; Now eax contains the offset address to draw the character at, so just add it to the base address + ; of video memory (Stored in edi) + ;------------------------------- + + xor ecx, ecx + add edi, eax ; add it to the base address + + ;-------------------------------; + ; Watch for new line ; + ;-------------------------------; + + cmp bl, 0x0A ; is it a newline character? + je .Row ; yep--go to next row + + ;-------------------------------; + ; Print a character ; + ;-------------------------------; + + mov dl, bl ; Get character + mov dh, CHAR_ATTRIB ; the character attribute + mov word [edi], dx ; write to video display + + ;-------------------------------; + ; Update next position ; + ;-------------------------------; + + inc byte [_CurX] ; go to next character +; cmp byte [_CurX], COLS ; are we at the end of the line? +; je .Row ; yep-go to next row + jmp .done ; nope, bail out + + ;-------------------------------; + ; Go to next row ; + ;-------------------------------; + +.Row: + mov byte [_CurX], 0 ; go back to col 0 + inc byte [_CurY] ; go to next row + + ;-------------------------------; + ; Restore registers & return ; + ;-------------------------------; + +.done: + popa ; restore registers and return + ret + +;**************************************************; +; Puts32 () +; - Prints a null terminated string +; parm\ EBX = address of string to print +;**************************************************; + +Puts32: + + ;-------------------------------; + ; Store registers ; + ;-------------------------------; + + pusha ; save registers + push ebx ; copy the string address + pop edi + +.loop: + + ;-------------------------------; + ; Get character ; + ;-------------------------------; + + mov bl, byte [edi] ; get next character + cmp bl, 0 ; is it 0 (Null terminator)? + je .done ; yep-bail out + + ;-------------------------------; + ; Print the character ; + ;-------------------------------; + + call Putch32 ; Nope-print it out + + ;-------------------------------; + ; Go to next character ; + ;-------------------------------; + + inc edi ; go to next character + jmp .loop + +.done: + + ;-------------------------------; + ; Update hardware cursor ; + ;-------------------------------; + + ; Its more efficiant to update the cursor after displaying + ; the complete string because direct VGA is slow + + mov bh, byte [_CurY] ; get current position + mov bl, byte [_CurX] + call MovCur ; update cursor + + popa ; restore registers, and return + ret + +;**************************************************; +; MoveCur () +; - Update hardware cursor +; parm/ bh = Y pos +; parm/ bl = x pos +;**************************************************; + +bits 32 + +MovCur: + + pusha ; save registers (aren't you getting tired of this comment?) + + ;-------------------------------; + ; Get current position ; + ;-------------------------------; + + ; Here, _CurX and _CurY are relitave to the current position on screen, not in memory. + ; That is, we don't need to worry about the byte alignment we do when displaying characters, + ; so just follow the forumla: location = _CurX + _CurY * COLS + + xor eax, eax + mov ecx, COLS + mov al, bh ; get y pos + mul ecx ; multiply y*COLS + add al, bl ; Now add x + mov ebx, eax + + ;--------------------------------------; + ; Set low byte index to VGA register ; + ;--------------------------------------; + + mov al, 0x0f + mov dx, 0x03D4 + out dx, al + + mov al, bl + mov dx, 0x03D5 + out dx, al ; low byte + + ;---------------------------------------; + ; Set high byte index to VGA register ; + ;---------------------------------------; + + xor eax, eax + + mov al, 0x0e + mov dx, 0x03D4 + out dx, al + + mov al, bh + mov dx, 0x03D5 + out dx, al ; high byte + + popa + ret + +;**************************************************; +; ClrScr32 () +; - Clears screen +;**************************************************; + +bits 32 + +ClrScr32: + + pusha + cld + mov edi, VIDMEM + mov cx, 2000 + mov ah, CHAR_ATTRIB + mov al, ' ' + rep stosw + + mov byte [_CurX], 0 + mov byte [_CurY], 0 + popa + ret + +;**************************************************; +; GotoXY () +; - Set current X/Y location +; parm\ AL=X position +; parm\ AH=Y position +;**************************************************; + +bits 32 + +GotoXY: + pusha + mov [_CurX], al ; just set the current position + mov [_CurY], ah + popa + ret + + + + +%endif ;__STDIO_INC_67343546FDCC56AAB872_INCLUDED__ diff --git a/timer.c b/timer.c deleted file mode 100644 index 3e09c41..0000000 --- a/timer.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -int timer_ticks = 0; -int timer_hz; - -void timer_phase(int hz) -{ - int divisor = 1193180/hz; // Calculate the divisor - outportb(0x43, 0x36); // Set our command byte 0x36 - outportb(0x40, divisor&0xFF); // Set low byte - outportb(0x40, divisor>>8); // Set high byte - timer_hz = hz; -} - -void timer_clock (int x, int y, int secs) -{ - int s, m, h; - char arr[9] = {0,0,0,0,0,0,0,0,0}; - - s = secs%60; - m = (secs/60)%60; - h = secs/3600; - - arr[0] = (h/10)%10 + '0'; if (arr[0]=='0') arr[0] = ' '; - arr[1] = h%10 + '0'; - - arr[3] = (m/10) + '0'; - arr[4] = m%10 + '0'; - - arr[6] = s/10 + '0'; - arr[7] = s%10 + '0'; - - if (secs%2 == 0) { - arr[2] = ' '; - arr[5] = ' '; - } - else { - arr[2] = ':'; - arr[5] = ':'; - } - - puts_pos(x, y, arr); -} - - -void timer_handler(regs *r) -{ - timer_ticks++; - - if (timer_ticks % timer_hz) { - timer_clock (70, 0, timer_ticks / timer_hz); - } -} \ No newline at end of file