diff options
-rw-r--r-- | Makefile | 55 | ||||
-rw-r--r-- | boot/Makefile | 10 | ||||
-rw-r--r-- | boot/load.S | 254 | ||||
-rw-r--r-- | driver/Makefile | 6 | ||||
-rw-r--r-- | driver/console.c | 61 | ||||
-rw-r--r-- | driver/console_old.S | 14 | ||||
-rw-r--r-- | driver/dma.c | 31 | ||||
-rw-r--r-- | driver/floppy.c | 214 | ||||
-rw-r--r-- | driver/keyboard.c | 268 | ||||
-rw-r--r-- | include/asm/boot.h | 9 | ||||
-rw-r--r-- | include/asm/interrupt.h | 1 | ||||
-rw-r--r-- | include/console.h | 6 | ||||
-rw-r--r-- | include/dma.h | 47 | ||||
-rw-r--r-- | include/floppy.h | 30 | ||||
-rw-r--r-- | include/keyboard.h | 35 | ||||
-rw-r--r-- | include/system.h | 21 | ||||
-rw-r--r-- | include/timer.h | 5 | ||||
-rw-r--r-- | system/Makefile | 6 | ||||
-rw-r--r-- | system/ansi.S | 74 | ||||
-rw-r--r-- | system/hex.c | 31 | ||||
-rw-r--r-- | system/interrupt.S | 320 | ||||
-rw-r--r-- | system/kernel.c | 115 | ||||
-rw-r--r-- | system/timer.c | 9 |
23 files changed, 1622 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6cecf3e --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +VERSION = 0.01 pre-alpha + + +KERNEL_FILES = boot/boot.o system/system.o driver/driver.o + +SPECIAL_FILES = include/asm/version.h + + +kernel : version WINX + @echo + @echo WINX $(VERSION) compiled + @echo + +WINX : Makefile $(KERNEL_FILES) + @echo + @echo Linking kernel... + @ld -Ttext 0x0 -entry start -s --oformat binary -o WINX $(KERNEL_FILES) + +floppy : WINX + @echo + @echo Insert a blank 1.44 Mb floppy into drive 0 + @echo "Press <Enter> to continue, <^C> to abort..." + @read + @dd if=WINX of=/dev/fd0 bs=512 + @echo + @echo Done. + @echo + +clean : + @echo + @echo Cleanup... + @rm -f $(KERNEL_FILES) $(SPECIAL_FILES) $(BOOT_FILES) $(SYSTEM_FILES) $(DRIVER_FILES) + @echo OK + @echo + + +%.o : %.S + @echo Compiling $< + @cpp $< -I include | as -o $*.o + +%.o : %.c + @echo Compiling $< + @gcc -I include -c -O3 -fno-zero-initialized-in-bss -o $*.o $< + + +version : include/asm/version.h + @if ([ '$(shell cat "include/asm/version.h")' != '#define WINX_VERSION "$(VERSION)"' ]) then \ + echo "#define WINX_VERSION \"$(VERSION)\"" > include/asm/version.h; fi + +include/asm/version.h: + @touch "include/asm/version.h" + +include boot/Makefile +include system/Makefile +include driver/Makefile diff --git a/boot/Makefile b/boot/Makefile new file mode 100644 index 0000000..2fc7d3d --- /dev/null +++ b/boot/Makefile @@ -0,0 +1,10 @@ +BOOT_FILES = boot/load.o + +boot/boot.o : $(BOOT_FILES) + @echo Linking $*.o + @ld -r -o $*.o $(BOOT_FILES) + @echo + +boot/load.o : boot/load.S include/asm/version.h + @echo Compiling boot/load.S + @cpp boot/load.S -I include | as -o $*.o diff --git a/boot/load.S b/boot/load.S new file mode 100644 index 0000000..f7a6ba0 --- /dev/null +++ b/boot/load.S @@ -0,0 +1,254 @@ +/* boot.S - main bootup file */ + +#include <asm/boot.h> +#include <asm/version.h> + +GDT_SIZE = (gdt_end - gdt) +IDT_SIZE = (idt_end - idt) +KERNEL_TRACKS = ((KERNEL_BLOCKS+DISK_SECTORS_PER_TRACK-1)/DISK_SECTORS_PER_TRACK) + + +.text + +.code16 + +.global start + +start: + +xor %ax,%ax +int $0x13 + +# Load kernel + +mov $0x0001,%cx +xor %dh,%dh +xor %bx,%bx +mov $0x50,%ax +mov %ax,%es + +load_kernel_loop: + +mov $0x02,%ah +mov $DISK_SECTORS_PER_TRACK,%al + +push %dx +int $0x13 +pop %dx + +jc error + +mov %es,%ax +add $(0x20*DISK_SECTORS_PER_TRACK),%ax +mov %ax,%es + + +add %dh,%ch +or %dh,%dh +jnz head0 +inc %dh +jmp head1 +head0: +xor %dh,%dh +head1: +cmp $(KERNEL_TRACKS/2),%ch +jb load_kernel_loop + +ljmp $0x50, $load + +load: + +cli + +mov %cs,%ax +mov %ax,%ds + +mov $0x01,%ah +mov $0b0010000000000000,%cx +int $0x10 + +mov $0x36,%al +out %al,$0x43 +mov $0x9B,%al +out %al,$0x40 +mov $0x2E,%al +out %al,$0x40 + +key_ready: +in $0x64,%al +and $0b00000010,%al +jnz key_ready +mov $0xED,%al +out %al,$0x60 +key_ready2: +in $0x64,%al +and $0b00000010,%al +jnz key_ready2 +xor %al,%al +out %al,$0x60 + +mov $0b00010001,%al +out %al,$0x20 +out %al,$0xA0 + +mov $0x20,%al +out %al,$0x21 + +mov $0x28,%al +out %al,$0xA1 + +mov $0b00000100,%al +out %al,$0x21 + +mov $0b00000010,%al +out %al,$0xA1 + +mov $0b00000001,%al +out %al,$0x21 +out %al,$0xA1 + +lgdt gdt_struct + +lidt idt_struct + +mov %cr0,%eax +or $1,%eax +mov %eax,%cr0 + +.byte 0xea +.word pmode +.word 8 + +pmode: + +.code32 + +mov $16,%ax +mov %ax,%ds + +mov $24,%ax +mov %ax,%ss +mov $0x1FFF,%esp + +sti + +cld + +pushl $'\f' +call print_char +addl $4,%esp + +pushl $0b00001111 +pushl $verstring +call print_attr +addl $8,%esp + +#call init_floppy + +#call test + +done: +xor %edx,%edx +call kb_read_keycode +or %eax,%eax +jz done +or %edx,%edx +jz done +and $0b10000000,%al +jnz done +pushl %edx +call print_char +addl $4,%esp +call floppy_proc +jmp done + +error: jmp error + + +.org 0x1FE + +.word 0xAA55 + +.org 0x200 + +.data + +gdt: + +.word 0, 0, 0, 0 # dummy +.word 0xFFFF, KERNEL_START, 0x9A00, 0x00CF # kernel code, 4 GB, code exec/read, 386 Segment +.word 0xFFFF, KERNEL_START, 0x9200, 0x00CF # kernel data, 4 GB, data read/write, 386 Segment +.word 0x2000, 0x8000, 0x9200, 0 # kernel stack, 8192 Bytes, data read/write, base address 0x8000 +.word 4000, 0x8000, 0x920B, 0 # VRAM, 4000 Bytes, data read/write, base address 0xB8000 +.word 0x0500, 0, 0x9200, 0 # BIOS data, 0x500 Bytes, data read/write, base address 0 + +gdt_end: + + +idt: + +.word EXC_DIV_ERROR, CODE_SEL, 0x8E00, 0 +.word EXC_DEBUG, CODE_SEL, 0x8E00, 0 +.word EXC_NMI, CODE_SEL, 0x8E00, 0 +.word EXC_BREAKPOINT, CODE_SEL, 0x8E00, 0 +.word EXC_INTO_OVERFLOW, CODE_SEL, 0x8E00, 0 +.word EXC_BOUND_OVERFLOW, CODE_SEL, 0x8E00, 0 +.word EXC_INVAL_OPCODE, CODE_SEL, 0x8E00, 0 +.word EXC_NO_COPROCESSOR, CODE_SEL, 0x8E00, 0 +.word EXC_DOUBLE_EXCEPTION, CODE_SEL, 0x8E00, 0 +.word EXC_COPROC_PROT_ERROR, CODE_SEL, 0x8E00, 0 +.word EXC_INVAL_TSS, CODE_SEL, 0x8E00, 0 +.word EXC_SEG_NOT_PRESENT, CODE_SEL, 0x8E00, 0 +.word EXC_STACK_FAULT, CODE_SEL, 0x8E00, 0 +.word EXC_GEN_PROT_VIOLATION, CODE_SEL, 0x8E00, 0 +.word EXC_PAGE_FAULT, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_COPROCESSOR_ERROR, CODE_SEL, 0x8E00, 0 +.word EXC_ALIGN_ERROR, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 +.word EXC_RESERVED, CODE_SEL, 0x8E00, 0 + +.word IRQ0, CODE_SEL, 0x8E00, 0 +.word IRQ1, CODE_SEL, 0x8E00, 0 +.word IRQ2, CODE_SEL, 0x8E00, 0 +.word IRQ3, CODE_SEL, 0x8E00, 0 +.word IRQ4, CODE_SEL, 0x8E00, 0 +.word IRQ5, CODE_SEL, 0x8E00, 0 +.word IRQ6, CODE_SEL, 0x8E00, 0 +.word IRQ7, CODE_SEL, 0x8E00, 0 +.word IRQ8, CODE_SEL, 0x8E00, 0 +.word IRQ9, CODE_SEL, 0x8E00, 0 +.word IRQ10, CODE_SEL, 0x8E00, 0 +.word IRQ11, CODE_SEL, 0x8E00, 0 +.word IRQ12, CODE_SEL, 0x8E00, 0 +.word IRQ13, CODE_SEL, 0x8E00, 0 +.word IRQ14, CODE_SEL, 0x8E00, 0 +.word IRQ15, CODE_SEL, 0x8E00, 0 + +idt_end: + + +gdt_struct: + +.word GDT_SIZE # gdt size +.long (KERNEL_START+gdt) # gdt base address + + +idt_struct: + +.word IDT_SIZE +.long (KERNEL_START+idt) + +verstring: .ascii "WINX " WINX_VERSION "\r\n\0" diff --git a/driver/Makefile b/driver/Makefile new file mode 100644 index 0000000..12d5789 --- /dev/null +++ b/driver/Makefile @@ -0,0 +1,6 @@ +DRIVER_FILES = driver/console.o driver/keyboard.o driver/floppy.o driver/dma.o + +driver/driver.o : $(DRIVER_FILES) + @echo Linking $*.o + @ld -r -o $*.o $(DRIVER_FILES) + @echo diff --git a/driver/console.c b/driver/console.c new file mode 100644 index 0000000..79f277c --- /dev/null +++ b/driver/console.c @@ -0,0 +1,61 @@ +/* console_cur.c - console functions */ + +#include <system.h> +#include <console.h> + +unsigned char console_flags = 0; +unsigned short console_cur_pos = 0; +unsigned char console_std_attr = 0x07; +unsigned char console_akt_char_attr = 0; +unsigned char cur_blink_counter = 0; + + +void console_cursor_on() { + if(console_flags & FLAG_BLINK_ON) {console_flags &= ~FLAG_BLINK_ON; console_cur_blink();} +} + +void console_cursor_off() { + if(console_flags & FLAG_BLINK_ON) {console_cur_blink(); console_flags |= FLAG_BLINK_ON;} +} + +void console_cur_blink() { + if(console_flags & FLAG_BLINK_ON) { + console_flags &= ~FLAG_BLINK_ON; + asm ( + "push %es\n" + "push %ebx\n" + "mov $32,%ax\n" + "mov %ax,%es\n" + "xor %ebx,%ebx\n" + "mov console_cur_pos,%bx\n" + "shl $1,%ebx\n" + "inc %ebx\n" + "mov console_akt_char_attr,%al\n" + "mov %al,%es:(%ebx)\n" + "pop %ebx\n" + "pop %es" + ); + } + + else { + console_flags |= FLAG_BLINK_ON; + asm ( + "push %es\n" + "push %ebx\n" + "mov $32,%ax\n" + "mov %ax,%es\n" + "xor %ebx,%ebx\n" + "mov console_cur_pos,%bx\n" + "shl $1,%ebx\n" + "inc %ebx\n" + "mov console_std_attr,%al\n" + "rol $4,%al\n" + "and $0b01110111,%al\n" + "mov %es:(%ebx),%ah\n" + "mov %ah,console_akt_char_attr\n" + "mov %al,%es:(%ebx)\n" + "pop %ebx\n" + "pop %es" + ); + } +} diff --git a/driver/console_old.S b/driver/console_old.S new file mode 100644 index 0000000..9e105c9 --- /dev/null +++ b/driver/console_old.S @@ -0,0 +1,14 @@ +.data + +.global console_cur_pos, console_std_attr, console_akt_char_attr, cur_blink_counter, console_flags + +console_cur_pos: .word 0 +console_std_attr: .byte 0b00000111 +console_akt_char_attr: .byte 0 + +cur_blink_counter: .byte 0 + + +.global CUR_BLINK + +CUR_BLINK = 50 diff --git a/driver/dma.c b/driver/dma.c new file mode 100644 index 0000000..dc48de2 --- /dev/null +++ b/driver/dma.c @@ -0,0 +1,31 @@ +/* dma.c - DMA functions */ + +#include <system.h> +#include <dma.h> + +void dma_enable(unsigned char dma_nr) { + OUT_PORT(dma_nr & 3, PORT_DMA_MASK); +} + +void dma_disable(unsigned char dma_nr) { + OUT_PORT((dma_nr & 3) | 4, PORT_DMA_MASK); +} + +void dma_set_base_addr(unsigned char dma_nr, void *addr) { + OUT_PORT((unsigned long)addr & 0xFF, (dma_nr & 3)*2); + OUT_PORT(((unsigned long)addr >> 8) & 0xFF, (dma_nr & 3)*2); + OUT_PORT(((unsigned long)addr >> 16) & 0xFF, dma_page_ports[dma_nr & 3]); +} + +void dma_set_word_count(unsigned char dma_nr, unsigned short words) { + OUT_PORT(words & 0xFF, ((dma_nr & 3)*2)+1); + OUT_PORT((words >> 8) & 0xFF, ((dma_nr & 3)*2)+1); +} + +void dma_set_mode(unsigned char dma_nr, unsigned char mode) { + OUT_PORT(mode | (dma_nr & 3), PORT_DMA_MODE); +} + +void dma_clear_ff() { + OUT_PORT(0, PORT_DMA_FF); +} diff --git a/driver/floppy.c b/driver/floppy.c new file mode 100644 index 0000000..6b5d2d9 --- /dev/null +++ b/driver/floppy.c @@ -0,0 +1,214 @@ +/* floppy.c - floppy disk driver */ + +#include <system.h> +#include <floppy.h> +#include <dma.h> +#include <timer.h> + + +unsigned char floppy_flags = 0; +unsigned char floppy_num_drives = 0; +unsigned char floppy_drive_type; +unsigned char floppy_state = FLOPPY_STATE_IDLE; +unsigned char floppy_waiting = 0; +unsigned char floppy_requests = 0; +unsigned char ST0, ST1, ST2, ST3; + +struct floppy_request request; + + +static inline void send_floppy_byte(unsigned char byte) { + unsigned char status; + do IN_PORT_PP(PORT_FLOPPY_STATUS, status); while((status & 0xC0) != 0x80); + OUT_PORT(byte, PORT_FLOPPY_COMMAND_DATA); +} + +static inline unsigned char recv_floppy_byte() { + unsigned char status; + do IN_PORT_PP(PORT_FLOPPY_STATUS, status); while((status & 0xD0) != 0xD0); + IN_PORT_PP(PORT_FLOPPY_COMMAND_DATA, status); + return status; +} + +static inline void recalibrate(unsigned char drive) { + floppy_state = FLOPPY_STATE_RECALIBRATE; + floppy_waiting = 1; + send_floppy_byte(0x07); + send_floppy_byte(drive); +} + +void test() { + read_floppy_sectors(0, 0, 0, 1, 1); +} + +void init_floppy() { + unsigned short info; + unsigned char i; + + + //Kill motor + OUT_PORT(0x0C, PORT_FLOPPY_DOR); + + //List drives + asm( + "mov $0x28,%%ax\n" + "mov %%ax,%%fs\n" + "mov %%fs:0x0410,%0" + : "=a" (info) + ); + + if(info & 1) { + floppy_num_drives = ((info >> 6) & 3) + 1; + if(floppy_num_drives > 2) floppy_num_drives = 2; + if(floppy_num_drives == 1) print("1 floppy drive found\r\n"); + else print("2 floppy drives found\r\n"); + } + else { + print(" No floppy drives found...\r\n"); + return; + } + + + OUT_PORT(0x10, 0x70); + IN_PORT(0x71, floppy_drive_type); + + if((floppy_drive_type >> 4) & 0x0F) { + print(" fd0: "); + if(((floppy_drive_type >> 4) & 0x0F) > 5) print("unknown"); + else print(floppy_drive_types[(floppy_drive_type >> 4) & 0x0F]); + print("\r\n"); + } + + if(floppy_drive_type & 0x0F) { + print(" fd1: "); + if((floppy_drive_type & 0x0F) > 5) print("unknown"); + else print(floppy_drive_types[floppy_drive_type & 0x0F]); + print("\r\n"); + } + + // configure + + /*OUT_PORT(0x13, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0x1F, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0, PORT_FLOPPY_COMMAND_DATA); + + // specify + + OUT_PORT(0x03, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0xCF, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0x06, PORT_FLOPPY_COMMAND_DATA);*/ +} + +int read_floppy_sectors(unsigned char drive, unsigned char cylinder, unsigned char head, unsigned char sector, unsigned char sector_count) { + unsigned char i; + + // test parameters + if(drive != 0 && drive != 1) return 1; + else if((drive == 0) && (((floppy_drive_type >> 4) & 0x0F) != 4)) return 2; + else if((drive == 1) && ((floppy_drive_type & 0x0F) != 4)) return 2; + + if(!sector_count) return 3; + + if(floppy_state == FLOPPY_STATE_IDLE) { + + //Activate drive motor + OUT_PORT((1 << (4 + drive)) | 0x0C, PORT_FLOPPY_DOR); + + print("TEST\n"); + + sleep(5000); + + print("TEST\n"); + + //Recalibrate + //recalibrate(drive); + } + + return 0; +} + +void floppy_proc() { + unsigned char i; + + /*IN_PORT(PORT_FLOPPY_STATUS, i); + print_hex_byte(i);*/ + //dma_clear_ff(); + //IN_PORT(0x04, i); + //print_hex_byte(i); + //IN_PORT(0x04, i); + //print_hex_byte(i); + /*IN_PORT(0x81, i); + print_hex_byte(i);*/ + //IN_PORT(0x05, i); + //print_hex_byte(i); + /*IN_PORT(0x05, i); + print_hex_byte(i);*/ + + if(floppy_waiting) return; + + if(floppy_state == FLOPPY_STATE_RECALIBRATE) { + floppy_state = FLOPPY_STATE_READ; + floppy_waiting = 1; + + dma_disable(2); + dma_clear_ff(); + dma_set_mode(2, DMA_MODE_SINGLE | DMA_MODE_READ | DMA_MODE_INC_ADDR); + dma_set_base_addr(2, (void*)0x200000); + dma_set_word_count(2, 0xFFFF); + dma_enable(2); + + send_floppy_byte(0xE6); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x02); + send_floppy_byte(0x02); + send_floppy_byte(0x01); + send_floppy_byte(0x1B); + send_floppy_byte(0xFF); + } +} + +void floppy_IRQ() { + //floppy_waiting = 0; + switch(floppy_state) { + case FLOPPY_STATE_RECALIBRATE: + print("Recalibrate FDC interrupt\n"); + //IN_PORT(PORT_FLOPPY_STATUS, i); + //print_hex_byte(i); + //floppy_state = FLOPPY_STATE_READ; + //floppy_waiting = 0; + send_floppy_byte(0x08); + //print_hex_byte(recv_floppy_byte()); + //print_hex_byte(recv_floppy_byte()); + ST0 = recv_floppy_byte(); + ST1 = recv_floppy_byte(); + + /*dma_disable(2); + dma_clear_ff(); + dma_set_mode(2, DMA_MODE_SINGLE | DMA_MODE_READ | DMA_MODE_INC_ADDR); + dma_set_base_addr(2, (void*)0x100000); + dma_set_word_count(2, 512); + dma_enable(2); + + send_floppy_byte(0xE6); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x01); + send_floppy_byte(0x02); + send_floppy_byte(0x01); + send_floppy_byte(0x1B); + send_floppy_byte(0xFF);*/ + + break; + case FLOPPY_STATE_READ: + print("Read FDC interrupt\n"); + floppy_state = FLOPPY_STATE_IDLE; + print_hex_long(*(unsigned long*)0x1FFB00); + break; + default: + print("Unexpected FDC interrupt!\n"); + } +} diff --git a/driver/keyboard.c b/driver/keyboard.c new file mode 100644 index 0000000..26a12f0 --- /dev/null +++ b/driver/keyboard.c @@ -0,0 +1,268 @@ +/* keyboard.c - keyboard functions */ + +#include <system.h> +#include <keyboard.h> +#include <console.h> + +unsigned short keyflags = 0; +unsigned short key_extended_buffer; +unsigned char keybuffer[256]; +unsigned char keybuffer_pointer = 0, keybuffer_count = 0; + +unsigned char keydata[128] = { + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xDF, '\'', '\b', '\t', + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 0xFC, '+', '\n', 0, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0xF6, 0xE4, '^', 0, '#', 'y', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '-', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0, + 0, 0, 0, 0, 0, 0, '<', 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +unsigned char keydata_shift[128] = { + 0, 0, '!', '"', 0xA7, '$', '%', '&', '/', '(', ')', '=', '?', '`', '\b', '\t', + 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 0xDC, '*', '\n', 0, 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xD6, 0xC4, 0xB0, 0, '\'', 'Y', 'X', 'C', 'V', + 'B', 'N', 'M', ';', ':', '_', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0, + 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +unsigned char keydata_extended[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +unsigned char keydata_altgr[128] = { + 0, 0, 0, 0xB2, 0xB3, 0, 0, 0, '{', '[', ']', '}', '\\', 0, '\b', '\t', + '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', '\n', 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0xB5, 0, 0, 0, 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0, + 0, 0, 0, 0, 0, 0, '|', 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +unsigned char keydata_numlock[13] = { + '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ',' +}; + + +void update_leds() { + register unsigned char al asm("%al"); + do { + asm ( + "in $0x64,%al\n" + "and $0b00000010,%al\n" + ); + } while (al); + asm ( + "mov $0xED,%al\n" + "out %al,$0x60\n" + ); + do { + asm ( + "in $0x64,%al\n" + "and $0b00000010,%al\n" + ); + } while (al); + asm ( + "mov %0,%%eax\n" + "and $0b11100000,%%al\n" + "shr $5,%%al\n" + "out %%al,$0x60\n" + : : "m" (keyflags) + ); +} + + +void kb_write_keycode() { + + unsigned char keycode; + unsigned long fullcode; + unsigned char ansicode = 0; + + unsigned char *keytable = keydata; + + asm ("mov %%al,%0" : "=m" (keycode)); + + fullcode = (keycode & KEY_CODE); + + if(keycode==ACKNOWLEDGE_CODE) return; + + else if(keycode==EXTENDED0_CODE) {keyflags |= FLAG_EXTENDED_KEY; key_extended_buffer = EXTENDED0_CODE;} + + else if(keycode==EXTENDED1_CODE) {keyflags |= FLAG_EXTENDED_KEY; key_extended_buffer = EXTENDED1_CODE;} + + else { + + if(keyflags & FLAG_EXTENDED_KEY) { + if(key_extended_buffer==EXTENDED0_CODE) { + fullcode = ((keycode & KEY_CODE) | (EXTENDED0_CODE << 8)); + keyflags &= ~FLAG_EXTENDED_KEY; + } + else if(key_extended_buffer==EXTENDED1_CODE) { + fullcode = ((keycode & KEY_CODE) | (EXTENDED1_CODE << 8)); + key_extended_buffer = fullcode; + } + else { + fullcode = ((keycode & KEY_CODE) | (((unsigned long)key_extended_buffer) << 8)); + keyflags &= ~FLAG_EXTENDED_KEY; + } + } + + + if(keycode & KEY_RELEASE) { + switch(fullcode) { + case NUMLOCK_CODE: + keyflags &= ~FLAG_NUMLOCK_PRESSED; + break; + case SCROLLLOCK_CODE: + keyflags &= ~FLAG_SCROLLLOCK_PRESSED; + break; + case CAPSLOCK_CODE: + keyflags &= ~FLAG_CAPSLOCK_PRESSED; + break; + case LSHIFT_CODE: + keyflags &= ~FLAG_LSHIFT_PRESSED; + break; + case RSHIFT_CODE: + keyflags &= ~FLAG_RSHIFT_PRESSED; + break; + case LALT_CODE: + keyflags &= ~FLAG_LALT_PRESSED; + break; + case RALT_CODE: + keyflags &= ~FLAG_RALT_PRESSED; + break; + case LCTRL_CODE: + keyflags &= ~FLAG_LCTRL_PRESSED; + break; + case RCTRL_CODE: + keyflags &= ~FLAG_RCTRL_PRESSED; + break; + default: + if((keyflags & FLAG_NUMLOCK_ACTIVE) && (0x47 <= (fullcode & ~KEY_RELEASE)) && ((fullcode & ~KEY_RELEASE) <= 0x53)) + ansicode = keydata_numlock[(keycode & KEY_CODE) - 0x47]; + else { + if((fullcode & (EXTENDED0_CODE << 8)) == (EXTENDED0_CODE << 8)) keytable = keydata_extended; + else if(keyflags & FLAG_RALT_PRESSED) keytable = keydata_altgr; + else if((keyflags & FLAG_LALT_PRESSED)/* && ((keyflags & FLAG_RCTRL_PRESSED) + || (keyflags & FLAG_LCTRL_PRESSED))*/) keytable = keydata_altgr; + else if(keyflags & (FLAG_LSHIFT_PRESSED | FLAG_RSHIFT_PRESSED | FLAG_CAPSLOCK_ACTIVE)) + keytable = keydata_shift; + ansicode = keytable[keycode & KEY_CODE]; + } + } + } + else { + switch(fullcode) { + case NUMLOCK_CODE: + if(keyflags & FLAG_NUMLOCK_PRESSED) return; + else { + keyflags |= FLAG_NUMLOCK_PRESSED; + if(keyflags & FLAG_NUMLOCK_ACTIVE) keyflags &= ~FLAG_NUMLOCK_ACTIVE; + else keyflags |= FLAG_NUMLOCK_ACTIVE; + update_leds(); + } + break; + case SCROLLLOCK_CODE: + if(keyflags & FLAG_SCROLLLOCK_PRESSED) return; + else { + keyflags |= FLAG_SCROLLLOCK_PRESSED; + if(keyflags & FLAG_SCROLLLOCK_ACTIVE) keyflags &= ~FLAG_SCROLLLOCK_ACTIVE; + else keyflags |= FLAG_SCROLLLOCK_ACTIVE; + update_leds(); + } + break; + case CAPSLOCK_CODE: + if(keyflags & FLAG_CAPSLOCK_PRESSED) return; + else { + keyflags |= FLAG_CAPSLOCK_PRESSED; + if(keyflags & FLAG_CAPSLOCK_ACTIVE) keyflags &= ~FLAG_CAPSLOCK_ACTIVE; + else keyflags |= FLAG_CAPSLOCK_ACTIVE; + update_leds(); + } + break; + case LSHIFT_CODE: + keyflags |= FLAG_LSHIFT_PRESSED; + break; + case RSHIFT_CODE: + keyflags |= FLAG_RSHIFT_PRESSED; + break; + case LALT_CODE: + keyflags |= FLAG_LALT_PRESSED; + break; + case RALT_CODE: + keyflags |= FLAG_RALT_PRESSED; + break; + case LCTRL_CODE: + keyflags |= FLAG_LCTRL_PRESSED; + break; + case RCTRL_CODE: + keyflags |= FLAG_RCTRL_PRESSED; + break; + default: + if((keyflags & FLAG_NUMLOCK_ACTIVE) && (0x47 <= fullcode) && (fullcode <= 0x53)) + ansicode = keydata_numlock[keycode - 0x47]; + else { + if((fullcode & (EXTENDED0_CODE << 8)) == (EXTENDED0_CODE << 8)) keytable = keydata_extended; + else if(keyflags & FLAG_RALT_PRESSED) keytable = keydata_altgr; + else if(keyflags & (FLAG_LSHIFT_PRESSED | FLAG_RSHIFT_PRESSED | FLAG_CAPSLOCK_ACTIVE)) + keytable = keydata_shift; + ansicode = keytable[keycode]; + } + } + } + } + if(keyflags & FLAG_BUFFER_FULL) return; + keybuffer[(keybuffer_pointer + keybuffer_count++) & 0xFF] = keycode; + keybuffer[(keybuffer_pointer + keybuffer_count++) & 0xFF] = ansicode; + if(keybuffer_count==0) keyflags |= FLAG_BUFFER_FULL; +} + + +void kb_read_keycode() { + unsigned long keycode = 0; + unsigned char ansicode = 0; + + if((keybuffer_count != 0) || (keyflags & FLAG_BUFFER_FULL)) { + keycode = keybuffer[keybuffer_pointer++]; + ansicode = keybuffer[keybuffer_pointer++]; + keybuffer_count-=2; + keyflags &= ~FLAG_BUFFER_FULL; + if(keycode == EXTENDED0_CODE) { + if(keybuffer_count != 0) { + keycode <<= 8; + keycode |= keybuffer[keybuffer_pointer++]; + ansicode = keybuffer[keybuffer_pointer++]; + keybuffer_count-=2; + } + } + else if(keycode == EXTENDED1_CODE) { + if(keybuffer_count != 0) { + keycode <<= 8; + keycode |= keybuffer[keybuffer_pointer++]; + ansicode = keybuffer[keybuffer_pointer++]; + keybuffer_count-=2; + if(keybuffer_count != 0) { + keycode <<= 8; + keycode |= keybuffer[keybuffer_pointer++]; + ansicode = keybuffer[keybuffer_pointer++]; + keybuffer_count-=2; + } + } + } + } + asm ("mov %0,%%eax; mov %1,%%dl" : : "m" (keycode), "m" (ansicode)); +} diff --git a/include/asm/boot.h b/include/asm/boot.h new file mode 100644 index 0000000..690f698 --- /dev/null +++ b/include/asm/boot.h @@ -0,0 +1,9 @@ +#define KERNEL_START 0x500 +#define KERNEL_BLOCKS 24 +#define DISK_SECTORS_PER_TRACK 18 + +#define CODE_SEL 0x08 +#define DATA_SEL 0x10 +#define STACK_SEL 0x18 +#define VRAM_SEL 0x20 +#define BIOS_SEL 0x28 diff --git a/include/asm/interrupt.h b/include/asm/interrupt.h new file mode 100644 index 0000000..c6924a7 --- /dev/null +++ b/include/asm/interrupt.h @@ -0,0 +1 @@ +#define CUR_BLINK 50 diff --git a/include/console.h b/include/console.h new file mode 100644 index 0000000..707fe3c --- /dev/null +++ b/include/console.h @@ -0,0 +1,6 @@ +void console_cur_blink(); +void console_cursor_on(); +void console_cursor_off(); + + +#define FLAG_BLINK_ON 0x01 diff --git a/include/dma.h b/include/dma.h new file mode 100644 index 0000000..3c45f7a --- /dev/null +++ b/include/dma.h @@ -0,0 +1,47 @@ +#define PORT_DMA_BASE_ADDR0 0x00 +#define PORT_DMA_WORD_COUNT0 0x01 +#define PORT_DMA_BASE_ADDR1 0x02 +#define PORT_DMA_WORD_COUNT1 0x03 +#define PORT_DMA_BASE_ADDR2 0x04 +#define PORT_DMA_WORD_COUNT2 0x05 +#define PORT_DMA_BASE_ADDR3 0x06 +#define PORT_DMA_WORD_COUNT3 0x07 + +#define PORT_DMA_COMMAND 0x08 +#define PORT_DMA_WRITE_REQUEST 0x09 +#define PORT_DMA_MASK 0x0A +#define PORT_DMA_MODE 0x0B +#define PORT_DMA_FF 0x0C + +#define PORT_DMA_PAGE0 0x87 +#define PORT_DMA_PAGE1 0x83 +#define PORT_DMA_PAGE2 0x81 +#define PORT_DMA_PAGE3 0x82 + +#define DMA_MODE_DEMAND 0x00 +#define DMA_MODE_SINGLE 0x40 +#define DMA_MODE_BLOCK 0x80 +#define DMA_MODE_CASCADE 0xC0 + +#define DMA_MODE_VERIFY 0x00 +#define DMA_MODE_READ 0x04 +#define DMA_MODE_WRITE 0x08 + +#define DMA_MODE_INC_ADDR 0x00 +#define DMA_MODE_DEC_ADDR 0x20 + + +static unsigned char dma_page_ports[4] = { + PORT_DMA_PAGE0, + PORT_DMA_PAGE1, + PORT_DMA_PAGE2, + PORT_DMA_PAGE3 +}; + + +void dma_enable(unsigned char dma_nr); +void dma_disable(unsigned char dma_nr); +void dma_set_base_addr(unsigned char dma_nr, void *addr); +void dma_set_word_count(unsigned char dma_nr, unsigned short words); +void dma_set_mode(unsigned char dma_nr, unsigned char mode); +void dma_clear_ff(); diff --git a/include/floppy.h b/include/floppy.h new file mode 100644 index 0000000..8d526ef --- /dev/null +++ b/include/floppy.h @@ -0,0 +1,30 @@ +#define PORT_FLOPPY_DOR 0x03F2 +#define PORT_FLOPPY_TAPE_DRIVE 0x03F3 +#define PORT_FLOPPY_SELECT_DATA_RATE 0x03F4 +#define PORT_FLOPPY_STATUS 0x03F4 +#define PORT_FLOPPY_COMMAND_DATA 0x03F5 +#define PORT_FLOPPY_DIR 0x03F7 + +#define FLOPPY_STATE_IDLE 0 +#define FLOPPY_STATE_RECALIBRATE 1 +#define FLOPPY_STATE_SEEK 2 +#define FLOPPY_STATE_READ 3 + + +struct floppy_request { + unsigned char command; + unsigned char drive; + unsigned char cylinder; + unsigned char head; + unsigned char sector; + unsigned char sector_count; + void *buffer; +}; + + +static unsigned char floppy_drive_types[6][8] = {"none", "360 KB", "1.2 MB", "720 KB", "1.44 MB", "2.88 MB"}; + + +void init_floppy(); +int read_floppy_sectors(unsigned char drive, unsigned char cylinder, unsigned char head, unsigned char sector, unsigned char sector_count); +void floppy_IRQ(); diff --git a/include/keyboard.h b/include/keyboard.h new file mode 100644 index 0000000..45c3c35 --- /dev/null +++ b/include/keyboard.h @@ -0,0 +1,35 @@ +#define LSHIFT_CODE 0x2A +#define RSHIFT_CODE 0x36 +#define NUMLOCK_CODE 0x45 +#define SCROLLLOCK_CODE 0x46 +#define CAPSLOCK_CODE 0x3A +#define ACKNOWLEDGE_CODE 0xFA +#define EXTENDED0_CODE 0xE0 +#define EXTENDED1_CODE 0xE1 +#define LALT_CODE 0x38 +#define RALT_CODE 0xE038 +#define PAUSE_CODE 0x00E11D45 +#define LCTRL_CODE 0x1D +#define RCTRL_CODE 0xE01D + +#define FLAG_BUFFER_FULL (1 << 0) +#define FLAG_EXTENDED_KEY (1 << 1) +#define FLAG_SCROLLLOCK_PRESSED (1 << 2) +#define FLAG_NUMLOCK_PRESSED (1 << 3) +#define FLAG_CAPSLOCK_PRESSED (1 << 4) +#define FLAG_SCROLLLOCK_ACTIVE (1 << 5) +#define FLAG_NUMLOCK_ACTIVE (1 << 6) +#define FLAG_CAPSLOCK_ACTIVE (1 << 7) +#define FLAG_LSHIFT_PRESSED (1 << 8) +#define FLAG_RSHIFT_PRESSED (1 << 9) +#define FLAG_LALT_PRESSED (1 << 10) +#define FLAG_RALT_PRESSED (1 << 11) +#define FLAG_LCTRL_PRESSED (1 << 12) +#define FLAG_RCTRL_PRESSED (1 << 13) + +#define KEY_RELEASE 0x80 +#define KEY_CODE 0x7F + + +void kb_write_keycode(); +void kb_read_keycode(); diff --git a/include/system.h b/include/system.h new file mode 100644 index 0000000..9440d6b --- /dev/null +++ b/include/system.h @@ -0,0 +1,21 @@ +#define IN_PORT(p,b) asm("in %1,%0" : "=a" ((unsigned char)(b)) : "d" ((unsigned short)(p)) ) +#define IN_PORT_P(p,b) asm("in %1,%0;in $0x80,%%al" : "=a" ((unsigned char)(b)) : "d" ((unsigned short)(p)) ) +#define IN_PORT_PP(p,b) asm("in %1,%0;in $0x80,%%al;in $0x80,%%al;in $0x80,%%al;in $0x80,%%al" \ + : "=a" ((unsigned char)(b)) : "d" ((unsigned short)(p)) ) +#define OUT_PORT(b,p) asm("out %0,%1" : : "a" ((unsigned char)(b)), "d" ((unsigned short)(p)) ) +#define OUT_PORT_P(b,p) asm("out %0,%1;in $0x80,%%al" : : "a" ((unsigned char)(b)), "d" ((unsigned short)(p)) ) +#define OUT_PORT_PP(b,p) asm("out %0,%1;in $0x80,%%al;in $0x80,%%al;in $0x80,%%al;in $0x80,%%al" \ + : : "a" ((unsigned char)(b)), "d" ((unsigned short)(p)) ) + +#define ANSI2ASCII(x) asm ("mov %0,%%dl;call ansi2ascii;mov %%dl,%0\n" : "+m" (x)) +#define ASCII2ANSI(x) asm ("mov %0,%%dl;call ascii2ansi;mov %%dl,%0\n" : "+m" (x)) + + +void print(unsigned char * text); +void print_attr(unsigned char * text, unsigned char attr); +void print_char(unsigned char text); +void print_char_attr(unsigned char text, unsigned char attr); + +void print_hex_byte(unsigned char hex); +void print_hex_word(unsigned short hex); +void print_hex_long(unsigned long hex); diff --git a/include/timer.h b/include/timer.h new file mode 100644 index 0000000..cfe05fc --- /dev/null +++ b/include/timer.h @@ -0,0 +1,5 @@ +typedef struct _TIMER { + unsigned long time; +} TIMER; + +void sleep(unsigned long ms); diff --git a/system/Makefile b/system/Makefile new file mode 100644 index 0000000..ade470d --- /dev/null +++ b/system/Makefile @@ -0,0 +1,6 @@ +SYSTEM_FILES = system/kernel.o system/interrupt.o system/ansi.o system/hex.o system/timer.o + +system/system.o : $(SYSTEM_FILES) + @echo Linking $*.o + @ld -r -o $*.o $(SYSTEM_FILES) + @echo diff --git a/system/ansi.S b/system/ansi.S new file mode 100644 index 0000000..d1b5f55 --- /dev/null +++ b/system/ansi.S @@ -0,0 +1,74 @@ +/* ansi.S - ANSI conversion functions */ + +.text + +.global ansi2ascii, ascii2ansi + +ascii2ansi: + push %eax + push %ds + mov $16,%ax + mov %ax,%ds + xor %eax,%eax + mov %dl,%al + add $ascii2ansi_tab,%eax + mov (%eax),%dl + pop %ds + pop %eax + ret + + +ansi2ascii: + push %eax + push %ds + mov $16,%ax + mov %ax,%ds + xor %eax,%eax + mov %dl,%al + add $ansi2ascii_tab,%eax + mov (%eax),%dl + pop %ds + pop %eax + ret + + +.data + +ansi2ascii_tab: + +.byte 0, ' ', ' ', ' ', ' ', ' ', ' ', 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, ' ', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/' +.byte '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?' +.byte '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' +.byte 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_' +.byte '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' +.byte 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', 0xAD, 0x9B, 0x9C, ' ', 0x9D, 0x7C, 0x15, ' ', ' ', 0xA6, 0xAE, 0xAA, 0x2D, ' ', ' ' +.byte 0xF8, 0xF1, 0xFD, ' ', 0x27, 0xE6, 0x14, 0xF9, ' ', ' ', 0xA7, 0xAF, 0xAC, 0xAB, ' ', 0xA8 +.byte ' ', ' ', ' ', ' ', 0x8E, 0x8F, 0x92, 0x80, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', 0xA5, ' ', ' ', ' ', ' ', 0x99, ' ', ' ', ' ', ' ', ' ', 0x9A, ' ', ' ', 0xE1 +.byte 0x85, 0xA0, 0x83, ' ', 0x84, 0x86, 0x91, 0x87, 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B +.byte ' ', 0xA4, 0x95, 0xA2, 0x93, ' ', 0x94, ' ', ' ', 0x97, 0xA3, 0x96, 0x81, ' ', ' ', 0x98 + + +ascii2ansi_tab: + +.byte 0, ' ', ' ', ' ', ' ', ' ', ' ', 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, ' ', '*' +.byte ' ', ' ', ' ', '!', '¶', '§', '_', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/' +.byte '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?' +.byte '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' +.byte 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_' +.byte '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' +.byte 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', ' ' +.byte 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è', 'ï', 'î', 'ì', 'Ä', 'Å' +.byte 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', '¢', '£', '¥', ' ', ' ' +.byte 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', ' ', '¬', '½', '¼', '¡', '«', '»' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', ' ', ' ', ' ', ' ', ' ', 'µ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +.byte ' ', '±', ' ', ' ', ' ', ' ', '÷', ' ', '°', '·', ' ', ' ', ' ', '²', '·', ' ' diff --git a/system/hex.c b/system/hex.c new file mode 100644 index 0000000..4374063 --- /dev/null +++ b/system/hex.c @@ -0,0 +1,31 @@ +/* hex.c - hexdecimal print functions */ + +#include <system.h> + + +extern unsigned char console_std_attr; + +static char hex_values[16] = "0123456789ABCDEF"; + +void print_hex_byte(unsigned char hex) { + print_char(hex_values[(hex >> 4) & 0x0F]); + print_char(hex_values[hex & 0x0F]); +} + +void print_hex_word(unsigned short hex) { + print_char(hex_values[(hex >> 12) & 0x0F]); + print_char(hex_values[(hex >> 8) & 0x0F]); + print_char(hex_values[(hex >> 4) & 0x0F]); + print_char(hex_values[hex & 0x0F]); +} + +void print_hex_long(unsigned long hex) { + print_char(hex_values[(hex >> 28) & 0x0F]); + print_char(hex_values[(hex >> 24) & 0x0F]); + print_char(hex_values[(hex >> 20) & 0x0F]); + print_char(hex_values[(hex >> 16) & 0x0F]); + print_char(hex_values[(hex >> 12) & 0x0F]); + print_char(hex_values[(hex >> 8) & 0x0F]); + print_char(hex_values[(hex >> 4) & 0x0F]); + print_char(hex_values[hex & 0x0F]); +} diff --git a/system/interrupt.S b/system/interrupt.S new file mode 100644 index 0000000..3791ce2 --- /dev/null +++ b/system/interrupt.S @@ -0,0 +1,320 @@ +/* interrupt.S - interrupt handlers */ + +#include <asm/interrupt.h> + +.text + +.global EXC_DIV_ERROR, EXC_DEBUG, EXC_NMI, EXC_BREAKPOINT +.global EXC_INTO_OVERFLOW, EXC_BOUND_OVERFLOW, EXC_INVAL_OPCODE, EXC_NO_COPROCESSOR +.global EXC_DOUBLE_EXCEPTION, EXC_COPROC_PROT_ERROR, EXC_INVAL_TSS, EXC_SEG_NOT_PRESENT +.global EXC_STACK_FAULT, EXC_GEN_PROT_VIOLATION, EXC_PAGE_FAULT, EXC_RESERVED +.global EXC_COPROCESSOR_ERROR, EXC_ALIGN_ERROR + +EXC_DIV_ERROR: + mov $16,%ax + mov %ax,%ds + pushl $exc_div_error_str + call print + addl $4,%esp + jmp looping + +EXC_DEBUG: + mov $16,%ax + mov %ax,%ds + pushl $exc_debug_str + call print + addl $4,%esp + jmp looping + +EXC_NMI: + mov $16,%ax + mov %ax,%ds + pushl $exc_nmi_str + call print + addl $4,%esp + jmp looping + +EXC_BREAKPOINT: + mov $16,%ax + mov %ax,%ds + pushl $exc_breakpoint_str + call print + addl $4,%esp + jmp looping + +EXC_INTO_OVERFLOW: + mov $16,%ax + mov %ax,%ds + pushl $exc_into_overflow_str + call print + addl $4,%esp + jmp looping + +EXC_BOUND_OVERFLOW: + mov $16,%ax + mov %ax,%ds + pushl $exc_bound_overflow_str + call print + addl $4,%esp + jmp looping + +EXC_INVAL_OPCODE: + mov $16,%ax + mov %ax,%ds + pushl $exc_inval_opcode_str + call print + addl $4,%esp + jmp looping + +EXC_NO_COPROCESSOR: + mov $16,%ax + mov %ax,%ds + pushl $exc_no_coprocessor_str + call print + addl $4,%esp + jmp looping + +EXC_DOUBLE_EXCEPTION: + mov $16,%ax + mov %ax,%ds + pushl $exc_double_exception_str + call print + addl $4,%esp + jmp looping + +EXC_COPROC_PROT_ERROR: + mov $16,%ax + mov %ax,%ds + pushl $exc_coproc_prot_error_str + call print + addl $4,%esp + jmp looping + +EXC_INVAL_TSS: + mov $16,%ax + mov %ax,%ds + pushl $exc_inval_tss_str + call print + addl $4,%esp + jmp looping + +EXC_SEG_NOT_PRESENT: + mov $16,%ax + mov %ax,%ds + pushl $exc_seg_not_present_str + call print + addl $4,%esp + jmp looping + +EXC_STACK_FAULT: + mov $16,%ax + mov %ax,%ds + pushl $exc_stack_fault_str + call print + addl $4,%esp + jmp looping + +EXC_GEN_PROT_VIOLATION: + mov $16,%ax + mov %ax,%ds + pushl $exc_gen_prot_violation_str + call print + addl $4,%esp + jmp looping + +EXC_PAGE_FAULT: + mov $16,%ax + mov %ax,%ds + pushl $exc_page_fault_str + call print + addl $4,%esp + jmp looping + +EXC_RESERVED: + mov $16,%ax + mov %ax,%ds + pushl $exc_reserved_str + call print + addl $4,%esp + jmp looping + +EXC_COPROCESSOR_ERROR: + mov $16,%ax + mov %ax,%ds + pushl $exc_coprocessor_error_str + call print + addl $4,%esp + jmp looping + +EXC_ALIGN_ERROR: + mov $16,%ax + mov %ax,%ds + pushl $exc_align_error_str + call print + addl $4,%esp + +looping: jmp looping + + +.data + +exc_div_error_str: .asciz "EXCEPTION: DIVIDE ERROR\r\n" +exc_debug_str: .asciz "EXCEPTION: DEBUG EXCEPTION\r\n" +exc_nmi_str: .asciz "EXCEPTION: NON-MASKABLE INTERRUPT\r\n" +exc_breakpoint_str: .asciz "EXCEPTION: BREAKPOINT\r\n" +exc_into_overflow_str: .asciz "EXCEPTION: OVERFLOW (INTO)\r\n" +exc_bound_overflow_str: .asciz "EXCEPTION: OVERFLOW (BOUND)\r\n" +exc_inval_opcode_str: .asciz "EXCEPTION: INVALID OPCODE\r\n" +exc_no_coprocessor_str: .asciz "EXCEPTION: NO COPROCESSOR\r\n" +exc_double_exception_str: .asciz "EXCEPTION: DOUBLE EXCEPTION\r\n" +exc_coproc_prot_error_str: .asciz "EXCEPTION: COPROCESSOR PROTECTION ERROR\r\n" +exc_inval_tss_str: .asciz "EXCEPTION: INVALID TSS SEGMENT\r\n" +exc_seg_not_present_str: .asciz "EXCEPTION: SEGMENT NOT PRESENT\r\n" +exc_stack_fault_str: .asciz "EXCEPTION: STACK FAULT\r\n" +exc_gen_prot_violation_str: .asciz "EXCEPTION: GENERAL PROTECTION VIOLATION\r\n" +exc_page_fault_str: .asciz "EXCEPTION: PAGE FAULT\r\n" +exc_reserved_str: .asciz "EXCEPTION: UNKNOWN ERROR\r\n" +exc_coprocessor_error_str: .asciz "EXCEPTION: COPROCESSOR ERROR\r\n" +exc_align_error_str: .asciz "EXCEPTION: ALIGNMENT ERROR\r\n" + + +.text + +.global IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15 + +IRQ0: + pusha + pushf + incb cur_blink_counter + cmpb $CUR_BLINK,cur_blink_counter + jb no_blink + subb $CUR_BLINK,cur_blink_counter + call console_cur_blink +no_blink: + cmpl $0,timers + je no_timer + decl timers +no_timer: + mov $0x20, %al + out %al, $0x20 + popf + popa + iret + +IRQ1: + push %ax + push %ds + push %edx + mov $16,%ax + mov %ax,%ds + in $0x60,%al + call kb_write_keycode + mov $0x20, %al + out %al, $0x20 + pop %edx + pop %ds + pop %ax + iret + +IRQ2: + push %ax + mov $0x20, %al + out %al, $0x20 + pop %ax + iret + +IRQ3: + push %ax + mov $0x20, %al + out %al, $0x20 + pop %ax + iret + +IRQ4: + push %ax + mov $0x20, %al + out %al, $0x20 + pop %ax + iret + +IRQ5: + push %ax + mov $0x20, %al + out %al, $0x20 + pop %ax + iret + +IRQ6: + #push %ax + pushf + pusha + call floppy_IRQ + mov $0x20, %al + out %al, $0x20 + #pop %ax + popa + popf + iret + +IRQ7: + push %ax + mov $0x20, %al + out %al, $0x20 + pop %ax + iret + +IRQ8: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ9: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ10: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ11: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ12: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ13: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ14: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret + +IRQ15: + push %ax + mov $0x20, %al + out %al, $0xA0 + pop %ax + iret diff --git a/system/kernel.c b/system/kernel.c new file mode 100644 index 0000000..e8ad3a9 --- /dev/null +++ b/system/kernel.c @@ -0,0 +1,115 @@ +/* kernel.c - kernel functions */ + +#include <system.h> +#include <console.h> + + +extern unsigned char console_std_attr; +extern unsigned short console_cur_pos; +extern unsigned char console_flags; + +unsigned char numprint = 0; + +#define PRINT_ON if(numprint == 0) { \ + asm("cli");\ + console_cursor_off();\ + }\ + numprint++ + +#define PRINT_OFF numprint--;\ + if(numprint == 0) {\ + console_cursor_on();\ + asm("sti");\ + } + + +void print(unsigned char * text) { + print_attr(text, console_std_attr); +} + +void print_attr(unsigned char * text, unsigned char attr) { + PRINT_ON; + while(*text) { + print_char_attr(*text, attr); + text++; + } + PRINT_OFF; +} + +void print_char(unsigned char text) { + print_char_attr(text, console_std_attr); +} + +void print_char_attr(unsigned char text, unsigned char attr) { + PRINT_ON; + switch(text) { + case 0x08: // backspace + if(console_cur_pos) console_cur_pos--; + break; + case 0x09: // tab + console_cur_pos += (8 - (console_cur_pos % 8)); + break; + case 0x0A: // new line + console_cur_pos += (80 - (console_cur_pos % 80)); + break; + case 0x0B: // home + case 0x0C: // form feed + console_cur_pos = 0; + asm( + "cld\n" + "mov $32,%%ax\n" + "mov %%ax,%%es\n" + "xor %%edi,%%edi\n" + "mov %0,%%ah\n" + "mov $0x20,%%al\n" + "mov $2000,%%ecx\n" + "rep stosw" + : : "m" (attr) + ); + break; + case 0x0D: // carriage return + console_cur_pos -= (console_cur_pos % 80); + break; + default: + ANSI2ASCII(text); + asm( + "cld\n" + "mov $32,%%ax\n" + "mov %%ax,%%es\n" + "xor %%eax,%%eax\n" + "mov %0,%%ax\n" + "shl $1,%%eax\n" + "mov %%eax,%%edi\n" + "mov %1,%%al\n" + "mov %2,%%ah\n" + "stosw" + : : "m" (console_cur_pos), "m" (text), "m" (attr) + ); + console_cur_pos++; + } + // scroll + if(console_cur_pos >= 2000) { + console_cur_pos -= 80; + asm( + "cld\n" + "push %%ds\n" + + "mov $32,%%ax\n" + "mov %%ax,%%ds\n" + "mov %%ax,%%es\n" + "mov $1920,%%ecx\n" + "mov $160,%%esi\n" + "xor %%edi,%%edi\n" + "rep movsw\n" + + "mov $80,%%cx\n" + "mov %%cs:%0,%%ah\n" + "mov $0x20,%%al\n" + "rep stosw\n" + + "pop %%ds" + : : "m" (console_std_attr) + ); + } + PRINT_OFF; +} diff --git a/system/timer.c b/system/timer.c new file mode 100644 index 0000000..847cfb0 --- /dev/null +++ b/system/timer.c @@ -0,0 +1,9 @@ +#include <timer.h> +#include <system.h> + +TIMER timers = {0}; + +void sleep(unsigned long ms) { + timers.time = (ms + 9)/10; + while(timers.time) asm("incl %0; decl %0" : "+m" (timers.time)); +} |