Stephen Downward 1 year ago
parent
commit
7a3a93d8cb
24 changed files with 740 additions and 738 deletions
  1. 12 12
      boot/32bit_print.asm
  2. 2 2
      boot/bootsect.asm
  3. 18 18
      boot/disk.asm
  4. 17 17
      boot/gdt.asm
  5. 22 22
      boot/print.asm
  6. 28 28
      boot/print_hex.asm
  7. 15 15
      boot/switch_pm.asm
  8. 9 9
      cpu/idt.c
  9. 12 12
      cpu/idt.h
  10. 143 143
      cpu/interrupt.asm
  11. 114 114
      cpu/isr.c
  12. 21 21
      cpu/ports.c
  13. 31 31
      cpu/timer.c
  14. 3 3
      cpu/types.h
  15. 26 26
      drivers/keyboard.c
  16. 14 14
      drivers/screen.c
  17. 35 35
      kernel/kernel.c
  18. 6 6
      libc/mem.c
  19. 33 33
      libc/string.c
  20. 14 14
      programs/texteditor.c
  21. 7 7
      util/bitmap.c
  22. 16 14
      util/commands.c
  23. 99 99
      util/font.c
  24. 43 43
      util/terminal.c

+ 12 - 12
boot/32bit_print.asm

@ -5,22 +5,22 @@ VIDEO_MEMORY equ 0xb8000
5 5
WHITE_OB_BLACK equ 0x0f ; the color byte for each character
6 6
7 7
print_string_pm:
8
    pusha
9
    mov edx, VIDEO_MEMORY
8
	pusha
9
	mov edx, VIDEO_MEMORY
10 10
11 11
print_string_pm_loop:
12
    mov al, [ebx] ; [ebx] is the address of our character
13
    mov ah, WHITE_OB_BLACK
12
	mov al, [ebx] ; [ebx] is the address of our character
13
	mov ah, WHITE_OB_BLACK
14 14
15
    cmp al, 0 ; check if end of string
16
    je print_string_pm_done
15
	cmp al, 0 ; check if end of string
16
	je print_string_pm_done
17 17
18
    mov [edx], ax ; store character + attribute in video memory
19
    add ebx, 1 ; next char
20
    add edx, 2 ; next video memory position
18
	mov [edx], ax ; store character + attribute in video memory
19
	add ebx, 1 ; next char
20
	add edx, 2 ; next video memory position
21 21
22
    jmp print_string_pm_loop
22
	jmp print_string_pm_loop
23 23
24 24
print_string_pm_done:
25
    popa
26
    ret
25
	popa
26
	ret

+ 2 - 2
boot/bootsect.asm

@ -30,8 +30,8 @@
30 30
	%include "boot/print_hex.asm"
31 31
32 32
load_bootloader:
33
    ;mov dh, [SEC_COUNT]
34
    ;call print_hex
33
	;mov dh, [SEC_COUNT]
34
	;call print_hex
35 35
	pusha
36 36
	
37 37
	call disk_load

+ 18 - 18
boot/disk.asm

@ -1,5 +1,5 @@
1 1
disk_load:
2
    pusha
2
	pusha
3 3
4 4
retry:	
5 5
	mov es, [CURRENT_REG_LOAD]
@ -9,22 +9,22 @@ retry:
9 9
	mov al, 1 ;Num sectors
10 10
	mov ch, [CYL_COUNT] ;Cylinder number
11 11
	mov dl, [BOOT_DRIVE]
12
    mov ah, 0x02 ; ah <- int 0x13 function. 0x02 = 'read'
13
    ;mov cl, 0x02 ; cl <- sector (0x01 .. 0x11)
14
                 ; 0x01 is our boot sector, 0x02 is the first 'available' sector
15
    ;mov ch, 0x00 ; ch <- cylinder (0x0 .. 0x3FF, upper 2 bits in 'cl')
16
    ; dl <- drive number. Our caller sets it as a parameter and gets it from BIOS
17
    ; (0 = floppy, 1 = floppy2, 0x80 = hdd, 0x81 = hdd2)
12
	mov ah, 0x02 ; ah <- int 0x13 function. 0x02 = 'read'
13
	;mov cl, 0x02 ; cl <- sector (0x01 .. 0x11)
14
				 ; 0x01 is our boot sector, 0x02 is the first 'available' sector
15
	;mov ch, 0x00 ; ch <- cylinder (0x0 .. 0x3FF, upper 2 bits in 'cl')
16
	; dl <- drive number. Our caller sets it as a parameter and gets it from BIOS
17
	; (0 = floppy, 1 = floppy2, 0x80 = hdd, 0x81 = hdd2)
18 18
19
    ; [es:bx] <- pointer to buffer where the data will be stored
20
    ; caller sets it up for us, and it is actually the standard location for int 13h
21
    int 0x13      ; BIOS interrupt
22
    jc disk_error ; if error (stored in the carry bit)
19
	; [es:bx] <- pointer to buffer where the data will be stored
20
	; caller sets it up for us, and it is actually the standard location for int 13h
21
	int 0x13	  ; BIOS interrupt
22
	jc disk_error ; if error (stored in the carry bit)
23 23
24
    cmp al, 1    ; BIOS also sets 'al' to the # of sectors read. Compare it.
25
    jne sectors_error
26
    popa
27
    ret
24
	cmp al, 1	; BIOS also sets 'al' to the # of sectors read. Compare it.
25
	jne sectors_error
26
	popa
27
	ret
28 28
29 29
30 30
disk_error:
@ -37,11 +37,11 @@ disk_error:
37 37
	jmp retry ;Try again. Forever.
38 38
39 39
sectors_error:
40
    mov bx, SECTORS_ERROR
41
    call print
40
	mov bx, SECTORS_ERROR
41
	call print
42 42
43 43
disk_loop:
44
    jmp $
44
	jmp $
45 45
46 46
DISK_ERROR: db "Disk read error", 0
47 47
SECTORS_ERROR: db "Incorrect number of sectors read", 0

+ 17 - 17
boot/gdt.asm

@ -1,34 +1,34 @@
1 1
gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
2
    ; the GDT starts with a null 8-byte
3
    dd 0x0 ; 4 byte
4
    dd 0x0 ; 4 byte
2
	; the GDT starts with a null 8-byte
3
	dd 0x0 ; 4 byte
4
	dd 0x0 ; 4 byte
5 5
6 6
; GDT for code segment. base = 0x00000000, length = 0xfffff
7 7
; for flags, refer to os-dev.pdf document, page 36
8 8
gdt_code: 
9
    dw 0xffff    ; segment length, bits 0-15
10
    dw 0x0       ; segment base, bits 0-15
11
    db 0x0       ; segment base, bits 16-23
12
    db 10011010b ; flags (8 bits)
13
    db 11001111b ; flags (4 bits) + segment length, bits 16-19
14
    db 0x0       ; segment base, bits 24-31
9
	dw 0xffff	; segment length, bits 0-15
10
	dw 0x0	   ; segment base, bits 0-15
11
	db 0x0	   ; segment base, bits 16-23
12
	db 10011010b ; flags (8 bits)
13
	db 11001111b ; flags (4 bits) + segment length, bits 16-19
14
	db 0x0	   ; segment base, bits 24-31
15 15
16 16
; GDT for data segment. base and length identical to code segment
17 17
; some flags changed, again, refer to os-dev.pdf
18 18
gdt_data:
19
    dw 0xffff
20
    dw 0x0
21
    db 0x0
22
    db 10010010b
23
    db 11001111b
24
    db 0x0
19
	dw 0xffff
20
	dw 0x0
21
	db 0x0
22
	db 10010010b
23
	db 11001111b
24
	db 0x0
25 25
26 26
gdt_end:
27 27
28 28
; GDT descriptor
29 29
gdt_descriptor:
30
    dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
31
    dd gdt_start ; address (32 bit)
30
	dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
31
	dd gdt_start ; address (32 bit)
32 32
33 33
; define some constants for later use
34 34
CODE_SEG equ gdt_code - gdt_start

+ 22 - 22
boot/print.asm

@ -1,37 +1,37 @@
1 1
print:
2
    pusha
2
	pusha
3 3
4 4
; keep this in mind:
5 5
; while (string[i] != 0) { print string[i]; i++ }
6 6
7 7
; the comparison for string end (null byte)
8 8
start:
9
    mov al, [bx] ; 'bx' is the base address for the string
10
    cmp al, 0 
11
    je done
9
	mov al, [bx] ; 'bx' is the base address for the string
10
	cmp al, 0 
11
	je done
12 12
13
    ; the part where we print with the BIOS help
14
    mov ah, 0x0e
15
    int 0x10 ; 'al' already contains the char
13
	; the part where we print with the BIOS help
14
	mov ah, 0x0e
15
	int 0x10 ; 'al' already contains the char
16 16
17
    ; increment pointer and do next loop
18
    add bx, 1
19
    jmp start
17
	; increment pointer and do next loop
18
	add bx, 1
19
	jmp start
20 20
21 21
done:
22
    popa
23
    ret
22
	popa
23
	ret
24 24
25 25
26 26
27 27
print_nl:
28
    pusha
29
    
30
    mov ah, 0x0e
31
    mov al, 0x0a ; newline char
32
    int 0x10
33
    mov al, 0x0d ; carriage return
34
    int 0x10
35
    
36
    popa
37
    ret
28
	pusha
29
	
30
	mov ah, 0x0e
31
	mov al, 0x0a ; newline char
32
	int 0x10
33
	mov al, 0x0d ; carriage return
34
	int 0x10
35
	
36
	popa
37
	ret

+ 28 - 28
boot/print_hex.asm

@ -1,46 +1,46 @@
1 1
; receiving the data in 'dx'
2 2
; For the examples we'll assume that we're called with dx=0x1234
3 3
print_hex:
4
    pusha
4
	pusha
5 5
6
    mov cx, 0 ; our index variable
6
	mov cx, 0 ; our index variable
7 7
8 8
; Strategy: get the last char of 'dx', then convert to ASCII
9 9
; Numeric ASCII values: '0' (ASCII 0x30) to '9' (0x39), so just add 0x30 to byte N.
10 10
; For alphabetic characters A-F: 'A' (ASCII 0x41) to 'F' (0x46) we'll add 0x40
11 11
; Then, move the ASCII byte to the correct position on the resulting string
12 12
hex_loop:
13
    cmp cx, 4 ; loop 4 times
14
    je end
15
    
16
    ; 1. convert last char of 'dx' to ascii
17
    mov ax, dx ; we will use 'ax' as our working register
18
    and ax, 0x000f ; 0x1234 -> 0x0004 by masking first three to zeros
19
    add al, 0x30 ; add 0x30 to N to convert it to ASCII "N"
20
    cmp al, 0x39 ; if > 9, add extra 8 to represent 'A' to 'F'
21
    jle step2
22
    add al, 7 ; 'A' is ASCII 65 instead of 58, so 65-58=7
13
	cmp cx, 4 ; loop 4 times
14
	je end
15
	
16
	; 1. convert last char of 'dx' to ascii
17
	mov ax, dx ; we will use 'ax' as our working register
18
	and ax, 0x000f ; 0x1234 -> 0x0004 by masking first three to zeros
19
	add al, 0x30 ; add 0x30 to N to convert it to ASCII "N"
20
	cmp al, 0x39 ; if > 9, add extra 8 to represent 'A' to 'F'
21
	jle step2
22
	add al, 7 ; 'A' is ASCII 65 instead of 58, so 65-58=7
23 23
24 24
step2:
25
    ; 2. get the correct position of the string to place our ASCII char
26
    ; bx <- base address + string length - index of char
27
    mov bx, HEX_OUT + 5 ; base + length
28
    sub bx, cx  ; our index variable
29
    mov [bx], al ; copy the ASCII char on 'al' to the position pointed by 'bx'
30
    ror dx, 4 ; 0x1234 -> 0x4123 -> 0x3412 -> 0x2341 -> 0x1234
25
	; 2. get the correct position of the string to place our ASCII char
26
	; bx <- base address + string length - index of char
27
	mov bx, HEX_OUT + 5 ; base + length
28
	sub bx, cx  ; our index variable
29
	mov [bx], al ; copy the ASCII char on 'al' to the position pointed by 'bx'
30
	ror dx, 4 ; 0x1234 -> 0x4123 -> 0x3412 -> 0x2341 -> 0x1234
31 31
32
    ; increment index and loop
33
    add cx, 1
34
    jmp hex_loop
32
	; increment index and loop
33
	add cx, 1
34
	jmp hex_loop
35 35
36 36
end:
37
    ; prepare the parameter and call the function
38
    ; remember that print receives parameters in 'bx'
39
    mov bx, HEX_OUT
40
    call print
37
	; prepare the parameter and call the function
38
	; remember that print receives parameters in 'bx'
39
	mov bx, HEX_OUT
40
	call print
41 41
42
    popa
43
    ret
42
	popa
43
	ret
44 44
45 45
HEX_OUT:
46
    db '0x0000',0 ; reserve memory for our new string
46
	db '0x0000',0 ; reserve memory for our new string

+ 15 - 15
boot/switch_pm.asm

@ -1,22 +1,22 @@
1 1
[bits 16]
2 2
switch_to_pm:
3
    cli ; 1. disable interrupts
4
    lgdt [gdt_descriptor] ; 2. load the GDT descriptor
5
    mov eax, cr0
6
    or eax, 0x1 ; 3. set 32-bit mode bit in cr0
7
    mov cr0, eax
8
    jmp CODE_SEG:init_pm ; 4. far jump by using a different segment
3
	cli ; 1. disable interrupts
4
	lgdt [gdt_descriptor] ; 2. load the GDT descriptor
5
	mov eax, cr0
6
	or eax, 0x1 ; 3. set 32-bit mode bit in cr0
7
	mov cr0, eax
8
	jmp CODE_SEG:init_pm ; 4. far jump by using a different segment
9 9
10 10
[bits 32]
11 11
init_pm: ; we are now using 32-bit instructions
12
    mov ax, DATA_SEG ; 5. update the segment registers
13
    mov ds, ax
14
    mov ss, ax
15
    mov es, ax
16
    mov fs, ax
17
    mov gs, ax
12
	mov ax, DATA_SEG ; 5. update the segment registers
13
	mov ds, ax
14
	mov ss, ax
15
	mov es, ax
16
	mov fs, ax
17
	mov gs, ax
18 18
19
    mov ebp, 0x90000 ; 6. update the stack right at the top of the free space
20
    mov esp, ebp
19
	mov ebp, 0x90000 ; 6. update the stack right at the top of the free space
20
	mov esp, ebp
21 21
22
    call BEGIN_PM ; 7. Call a well-known label with useful code
22
	call BEGIN_PM ; 7. Call a well-known label with useful code

+ 9 - 9
cpu/idt.c

@ -1,16 +1,16 @@
1 1
#include "idt.h"
2 2
3 3
void set_idt_gate(int n, u32 handler) {
4
    idt[n].low_offset = low_16(handler);
5
    idt[n].sel = KERNEL_CS;
6
    idt[n].always0 = 0;
7
    idt[n].flags = 0x8E; 
8
    idt[n].high_offset = high_16(handler);
4
	idt[n].low_offset = low_16(handler);
5
	idt[n].sel = KERNEL_CS;
6
	idt[n].always0 = 0;
7
	idt[n].flags = 0x8E; 
8
	idt[n].high_offset = high_16(handler);
9 9
}
10 10
11 11
void set_idt() {
12
    idt_reg.base = (u32) &idt;
13
    idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
14
    /* Don't make the mistake of loading &idt -- always load &idt_reg */
15
    __asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
12
	idt_reg.base = (u32) &idt;
13
	idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
14
	/* Don't make the mistake of loading &idt -- always load &idt_reg */
15
	__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
16 16
}

+ 12 - 12
cpu/idt.h

@ -8,23 +8,23 @@
8 8
9 9
/* How every interrupt gate (handler) is defined */
10 10
typedef struct {
11
    u16 low_offset; /* Lower 16 bits of handler function address */
12
    u16 sel; /* Kernel segment selector */
13
    u8 always0;
14
    /* First byte
15
     * Bit 7: "Interrupt is present"
16
     * Bits 6-5: Privilege level of caller (0=kernel..3=user)
17
     * Bit 4: Set to 0 for interrupt gates
18
     * Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
19
    u8 flags; 
20
    u16 high_offset; /* Higher 16 bits of handler function address */
11
	u16 low_offset; /* Lower 16 bits of handler function address */
12
	u16 sel; /* Kernel segment selector */
13
	u8 always0;
14
	/* First byte
15
	 * Bit 7: "Interrupt is present"
16
	 * Bits 6-5: Privilege level of caller (0=kernel..3=user)
17
	 * Bit 4: Set to 0 for interrupt gates
18
	 * Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
19
	u8 flags; 
20
	u16 high_offset; /* Higher 16 bits of handler function address */
21 21
} __attribute__((packed)) idt_gate_t ;
22 22
23 23
/* A pointer to the array of interrupt handlers.
24 24
 * Assembly instruction 'lidt' will read it */
25 25
typedef struct {
26
    u16 limit;
27
    u32 base;
26
	u16 limit;
27
	u32 base;
28 28
} __attribute__((packed)) idt_register_t;
29 29
30 30
#define IDT_ENTRIES 256

+ 143 - 143
cpu/interrupt.asm

@ -4,7 +4,7 @@
4 4
5 5
; Common ISR code
6 6
isr_common_stub:
7
    ; 1. Save CPU state
7
	; 1. Save CPU state
8 8
	pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
9 9
	mov ax, ds ; Lower 16-bits of eax = ds.
10 10
	push eax ; save the data segment descriptor
@ -14,10 +14,10 @@ isr_common_stub:
14 14
	mov fs, ax
15 15
	mov gs, ax
16 16
	
17
    ; 2. Call C handler
17
	; 2. Call C handler
18 18
	call isr_handler
19 19
	
20
    ; 3. Restore state
20
	; 3. Restore state
21 21
	pop eax 
22 22
	mov ds, ax
23 23
	mov es, ax
@ -31,24 +31,24 @@ isr_common_stub:
31 31
; Common IRQ code. Identical to ISR code except for the 'call' 
32 32
; and the 'pop ebx'
33 33
irq_common_stub:
34
    pusha 
35
    mov ax, ds
36
    push eax
37
    mov ax, 0x10
38
    mov ds, ax
39
    mov es, ax
40
    mov fs, ax
41
    mov gs, ax
42
    call irq_handler ; Different than the ISR code
43
    pop ebx  ; Different than the ISR code
44
    mov ds, bx
45
    mov es, bx
46
    mov fs, bx
47
    mov gs, bx
48
    popa
49
    add esp, 8
50
    sti
51
    iret 
34
	pusha 
35
	mov ax, ds
36
	push eax
37
	mov ax, 0x10
38
	mov ds, ax
39
	mov es, ax
40
	mov fs, ax
41
	mov gs, ax
42
	call irq_handler ; Different than the ISR code
43
	pop ebx  ; Different than the ISR code
44
	mov ds, bx
45
	mov es, bx
46
	mov fs, bx
47
	mov gs, bx
48
	popa
49
	add esp, 8
50
	sti
51
	iret 
52 52
	
53 53
; We don't get information about which interrupt was caller
54 54
; when the handler is run, so we will need to have a different handler
@ -110,221 +110,221 @@ global irq15
110 110
111 111
; 0: Divide By Zero Exception
112 112
isr0:
113
    cli
114
    push byte 0
115
    push byte 0
116
    jmp isr_common_stub
113
	cli
114
	push byte 0
115
	push byte 0
116
	jmp isr_common_stub
117 117
118 118
; 1: Debug Exception
119 119
isr1:
120
    cli
121
    push byte 0
122
    push byte 1
123
    jmp isr_common_stub
120
	cli
121
	push byte 0
122
	push byte 1
123
	jmp isr_common_stub
124 124
125 125
; 2: Non Maskable Interrupt Exception
126 126
isr2:
127
    cli
128
    push byte 0
129
    push byte 2
130
    jmp isr_common_stub
127
	cli
128
	push byte 0
129
	push byte 2
130
	jmp isr_common_stub
131 131
132 132
; 3: Int 3 Exception
133 133
isr3:
134
    cli
135
    push byte 0
136
    push byte 3
137
    jmp isr_common_stub
134
	cli
135
	push byte 0
136
	push byte 3
137
	jmp isr_common_stub
138 138
139 139
; 4: INTO Exception
140 140
isr4:
141
    cli
142
    push byte 0
143
    push byte 4
144
    jmp isr_common_stub
141
	cli
142
	push byte 0
143
	push byte 4
144
	jmp isr_common_stub
145 145
146 146
; 5: Out of Bounds Exception
147 147
isr5:
148
    cli
149
    push byte 0
150
    push byte 5
151
    jmp isr_common_stub
148
	cli
149
	push byte 0
150
	push byte 5
151
	jmp isr_common_stub
152 152
153 153
; 6: Invalid Opcode Exception
154 154
isr6:
155
    cli
156
    push byte 0
157
    push byte 6
158
    jmp isr_common_stub
155
	cli
156
	push byte 0
157
	push byte 6
158
	jmp isr_common_stub
159 159
160 160
; 7: Coprocessor Not Available Exception
161 161
isr7:
162
    cli
163
    push byte 0
164
    push byte 7
165
    jmp isr_common_stub
162
	cli
163
	push byte 0
164
	push byte 7
165
	jmp isr_common_stub
166 166
167 167
; 8: Double Fault Exception (With Error Code!)
168 168
isr8:
169
    cli
170
    push byte 8
171
    jmp isr_common_stub
169
	cli
170
	push byte 8
171
	jmp isr_common_stub
172 172
173 173
; 9: Coprocessor Segment Overrun Exception
174 174
isr9:
175
    cli
176
    push byte 0
177
    push byte 9
178
    jmp isr_common_stub
175
	cli
176
	push byte 0
177
	push byte 9
178
	jmp isr_common_stub
179 179
180 180
; 10: Bad TSS Exception (With Error Code!)
181 181
isr10:
182
    cli
183
    push byte 10
184
    jmp isr_common_stub
182
	cli
183
	push byte 10
184
	jmp isr_common_stub
185 185
186 186
; 11: Segment Not Present Exception (With Error Code!)
187 187
isr11:
188
    cli
189
    push byte 11
190
    jmp isr_common_stub
188
	cli
189
	push byte 11
190
	jmp isr_common_stub
191 191
192 192
; 12: Stack Fault Exception (With Error Code!)
193 193
isr12:
194
    cli
195
    push byte 12
196
    jmp isr_common_stub
194
	cli
195
	push byte 12
196
	jmp isr_common_stub
197 197
198 198
; 13: General Protection Fault Exception (With Error Code!)
199 199
isr13:
200
    cli
201
    push byte 13
202
    jmp isr_common_stub
200
	cli
201
	push byte 13
202
	jmp isr_common_stub
203 203
204 204
; 14: Page Fault Exception (With Error Code!)
205 205
isr14:
206
    cli
207
    push byte 14
208
    jmp isr_common_stub
206
	cli
207
	push byte 14
208
	jmp isr_common_stub
209 209
210 210
; 15: Reserved Exception
211 211
isr15:
212
    cli
213
    push byte 0
214
    push byte 15
215
    jmp isr_common_stub
212
	cli
213
	push byte 0
214
	push byte 15
215
	jmp isr_common_stub
216 216
217 217
; 16: Floating Point Exception
218 218
isr16:
219
    cli
220
    push byte 0
221
    push byte 16
222
    jmp isr_common_stub
219
	cli
220
	push byte 0
221
	push byte 16
222
	jmp isr_common_stub
223 223
224 224
; 17: Alignment Check Exception
225 225
isr17:
226
    cli
227
    push byte 0
228
    push byte 17
229
    jmp isr_common_stub
226
	cli
227
	push byte 0
228
	push byte 17
229
	jmp isr_common_stub
230 230
231 231
; 18: Machine Check Exception
232 232
isr18:
233
    cli
234
    push byte 0
235
    push byte 18
236
    jmp isr_common_stub
233
	cli
234
	push byte 0
235
	push byte 18
236
	jmp isr_common_stub
237 237
238 238
; 19: Reserved
239 239
isr19:
240
    cli
241
    push byte 0
242
    push byte 19
243
    jmp isr_common_stub
240
	cli
241
	push byte 0
242
	push byte 19
243
	jmp isr_common_stub
244 244
245 245
; 20: Reserved
246 246
isr20:
247
    cli
248
    push byte 0
249
    push byte 20
250
    jmp isr_common_stub
247
	cli
248
	push byte 0
249
	push byte 20
250
	jmp isr_common_stub
251 251
252 252
; 21: Reserved
253 253
isr21:
254
    cli
255
    push byte 0
256
    push byte 21
257
    jmp isr_common_stub
254
	cli
255
	push byte 0
256
	push byte 21
257
	jmp isr_common_stub
258 258
259 259
; 22: Reserved
260 260
isr22:
261
    cli
262
    push byte 0
263
    push byte 22
264
    jmp isr_common_stub
261
	cli
262
	push byte 0
263
	push byte 22
264
	jmp isr_common_stub
265 265
266 266
; 23: Reserved
267 267
isr23:
268
    cli
269
    push byte 0
270
    push byte 23
271
    jmp isr_common_stub
268
	cli
269
	push byte 0
270
	push byte 23
271
	jmp isr_common_stub
272 272
273 273
; 24: Reserved
274 274
isr24:
275
    cli
276
    push byte 0
277
    push byte 24
278
    jmp isr_common_stub
275
	cli
276
	push byte 0
277
	push byte 24
278
	jmp isr_common_stub
279 279
280 280
; 25: Reserved
281 281
isr25:
282
    cli
283
    push byte 0
284
    push byte 25
285
    jmp isr_common_stub
282
	cli
283
	push byte 0
284
	push byte 25
285
	jmp isr_common_stub
286 286
287 287
; 26: Reserved
288 288
isr26:
289
    cli
290
    push byte 0
291
    push byte 26
292
    jmp isr_common_stub
289
	cli
290
	push byte 0
291
	push byte 26
292
	jmp isr_common_stub
293 293
294 294
; 27: Reserved
295 295
isr27:
296
    cli
297
    push byte 0
298
    push byte 27
299
    jmp isr_common_stub
296
	cli
297
	push byte 0
298
	push byte 27
299
	jmp isr_common_stub
300 300
301 301
; 28: Reserved
302 302
isr28:
303
    cli
304
    push byte 0
305
    push byte 28
306
    jmp isr_common_stub
303
	cli
304
	push byte 0
305
	push byte 28
306
	jmp isr_common_stub
307 307
308 308
; 29: Reserved
309 309
isr29:
310
    cli
311
    push byte 0
312
    push byte 29
313
    jmp isr_common_stub
310
	cli
311
	push byte 0
312
	push byte 29
313
	jmp isr_common_stub
314 314
315 315
; 30: Reserved
316 316
isr30:
317
    cli
318
    push byte 0
319
    push byte 30
320
    jmp isr_common_stub
317
	cli
318
	push byte 0
319
	push byte 30
320
	jmp isr_common_stub
321 321
322 322
; 31: Reserved
323 323
isr31:
324
    cli
325
    push byte 0
326
    push byte 31
327
    jmp isr_common_stub
324
	cli
325
	push byte 0
326
	push byte 31
327
	jmp isr_common_stub
328 328
329 329
; IRQ handlers
330 330
irq0:

+ 114 - 114
cpu/isr.c

@ -11,141 +11,141 @@ isr_t interrupt_handlers[256];
11 11
/* Can't do this with a loop because we need the address
12 12
 * of the function names */
13 13
void isr_install() {
14
    set_idt_gate(0, (u32)isr0);
15
    set_idt_gate(1, (u32)isr1);
16
    set_idt_gate(2, (u32)isr2);
17
    set_idt_gate(3, (u32)isr3);
18
    set_idt_gate(4, (u32)isr4);
19
    set_idt_gate(5, (u32)isr5);
20
    set_idt_gate(6, (u32)isr6);
21
    set_idt_gate(7, (u32)isr7);
22
    set_idt_gate(8, (u32)isr8);
23
    set_idt_gate(9, (u32)isr9);
24
    set_idt_gate(10, (u32)isr10);
25
    set_idt_gate(11, (u32)isr11);
26
    set_idt_gate(12, (u32)isr12);
27
    set_idt_gate(13, (u32)isr13);
28
    set_idt_gate(14, (u32)isr14);
29
    set_idt_gate(15, (u32)isr15);
30
    set_idt_gate(16, (u32)isr16);
31
    set_idt_gate(17, (u32)isr17);
32
    set_idt_gate(18, (u32)isr18);
33
    set_idt_gate(19, (u32)isr19);
34
    set_idt_gate(20, (u32)isr20);
35
    set_idt_gate(21, (u32)isr21);
36
    set_idt_gate(22, (u32)isr22);
37
    set_idt_gate(23, (u32)isr23);
38
    set_idt_gate(24, (u32)isr24);
39
    set_idt_gate(25, (u32)isr25);
40
    set_idt_gate(26, (u32)isr26);
41
    set_idt_gate(27, (u32)isr27);
42
    set_idt_gate(28, (u32)isr28);
43
    set_idt_gate(29, (u32)isr29);
44
    set_idt_gate(30, (u32)isr30);
45
    set_idt_gate(31, (u32)isr31);
14
	set_idt_gate(0, (u32)isr0);
15
	set_idt_gate(1, (u32)isr1);
16
	set_idt_gate(2, (u32)isr2);
17
	set_idt_gate(3, (u32)isr3);
18
	set_idt_gate(4, (u32)isr4);
19
	set_idt_gate(5, (u32)isr5);
20
	set_idt_gate(6, (u32)isr6);
21
	set_idt_gate(7, (u32)isr7);
22
	set_idt_gate(8, (u32)isr8);
23
	set_idt_gate(9, (u32)isr9);
24
	set_idt_gate(10, (u32)isr10);
25
	set_idt_gate(11, (u32)isr11);
26
	set_idt_gate(12, (u32)isr12);
27
	set_idt_gate(13, (u32)isr13);
28
	set_idt_gate(14, (u32)isr14);
29
	set_idt_gate(15, (u32)isr15);
30
	set_idt_gate(16, (u32)isr16);
31
	set_idt_gate(17, (u32)isr17);
32
	set_idt_gate(18, (u32)isr18);
33
	set_idt_gate(19, (u32)isr19);
34
	set_idt_gate(20, (u32)isr20);
35
	set_idt_gate(21, (u32)isr21);
36
	set_idt_gate(22, (u32)isr22);
37
	set_idt_gate(23, (u32)isr23);
38
	set_idt_gate(24, (u32)isr24);
39
	set_idt_gate(25, (u32)isr25);
40
	set_idt_gate(26, (u32)isr26);
41
	set_idt_gate(27, (u32)isr27);
42
	set_idt_gate(28, (u32)isr28);
43
	set_idt_gate(29, (u32)isr29);
44
	set_idt_gate(30, (u32)isr30);
45
	set_idt_gate(31, (u32)isr31);
46 46
47
    // Remap the PIC
48
    port_byte_out(0x20, 0x11);
49
    port_byte_out(0xA0, 0x11);
50
    port_byte_out(0x21, 0x20);
51
    port_byte_out(0xA1, 0x28);
52
    port_byte_out(0x21, 0x04);
53
    port_byte_out(0xA1, 0x02);
54
    port_byte_out(0x21, 0x01);
55
    port_byte_out(0xA1, 0x01);
56
    port_byte_out(0x21, 0x0);
57
    port_byte_out(0xA1, 0x0); 
47
	// Remap the PIC
48
	port_byte_out(0x20, 0x11);
49
	port_byte_out(0xA0, 0x11);
50
	port_byte_out(0x21, 0x20);
51
	port_byte_out(0xA1, 0x28);
52
	port_byte_out(0x21, 0x04);
53
	port_byte_out(0xA1, 0x02);
54
	port_byte_out(0x21, 0x01);
55
	port_byte_out(0xA1, 0x01);
56
	port_byte_out(0x21, 0x0);
57
	port_byte_out(0xA1, 0x0); 
58 58
59
    // Install the IRQs
60
    set_idt_gate(32, (u32)irq0);
61
    set_idt_gate(33, (u32)irq1);
62
    set_idt_gate(34, (u32)irq2);
63
    set_idt_gate(35, (u32)irq3);
64
    set_idt_gate(36, (u32)irq4);
65
    set_idt_gate(37, (u32)irq5);
66
    set_idt_gate(38, (u32)irq6);
67
    set_idt_gate(39, (u32)irq7);
68
    set_idt_gate(40, (u32)irq8);
69
    set_idt_gate(41, (u32)irq9);
70
    set_idt_gate(42, (u32)irq10);
71
    set_idt_gate(43, (u32)irq11);
72
    set_idt_gate(44, (u32)irq12);
73
    set_idt_gate(45, (u32)irq13);
74
    set_idt_gate(46, (u32)irq14);
75
    set_idt_gate(47, (u32)irq15);
59
	// Install the IRQs
60
	set_idt_gate(32, (u32)irq0);
61
	set_idt_gate(33, (u32)irq1);
62
	set_idt_gate(34, (u32)irq2);
63
	set_idt_gate(35, (u32)irq3);
64
	set_idt_gate(36, (u32)irq4);
65
	set_idt_gate(37, (u32)irq5);
66
	set_idt_gate(38, (u32)irq6);
67
	set_idt_gate(39, (u32)irq7);
68
	set_idt_gate(40, (u32)irq8);
69
	set_idt_gate(41, (u32)irq9);
70
	set_idt_gate(42, (u32)irq10);
71
	set_idt_gate(43, (u32)irq11);
72
	set_idt_gate(44, (u32)irq12);
73
	set_idt_gate(45, (u32)irq13);
74
	set_idt_gate(46, (u32)irq14);
75
	set_idt_gate(47, (u32)irq15);
76 76
77
    set_idt(); // Load with ASM
77
	set_idt(); // Load with ASM
78 78
}
79 79
80 80
/* To print the message which defines every exception */
81 81
char *exception_messages[] = {
82
    "Division By Zero",
83
    "Debug",
84
    "Non Maskable Interrupt",
85
    "Breakpoint",
86
    "Into Detected Overflow",
87
    "Out of Bounds",
88
    "Invalid Opcode",
89
    "No Coprocessor",
82
	"Division By Zero",
83
	"Debug",
84
	"Non Maskable Interrupt",
85
	"Breakpoint",
86
	"Into Detected Overflow",
87
	"Out of Bounds",
88
	"Invalid Opcode",
89
	"No Coprocessor",
90 90
91
    "Double Fault",
92
    "Coprocessor Segment Overrun",
93
    "Bad TSS",
94
    "Segment Not Present",
95
    "Stack Fault",
96
    "General Protection Fault",
97
    "Page Fault",
98
    "Unknown Interrupt",
91
	"Double Fault",
92
	"Coprocessor Segment Overrun",
93
	"Bad TSS",
94
	"Segment Not Present",
95
	"Stack Fault",
96
	"General Protection Fault",
97
	"Page Fault",
98
	"Unknown Interrupt",
99 99
100
    "Coprocessor Fault",
101
    "Alignment Check",
102
    "Machine Check",
103
    "Reserved",
104
    "Reserved",
105
    "Reserved",
106
    "Reserved",
107
    "Reserved",
100
	"Coprocessor Fault",
101
	"Alignment Check",
102
	"Machine Check",
103
	"Reserved",
104
	"Reserved",
105
	"Reserved",
106
	"Reserved",
107
	"Reserved",
108 108
109
    "Reserved",
110
    "Reserved",
111
    "Reserved",
112
    "Reserved",
113
    "Reserved",
114
    "Reserved",
115
    "Reserved",
116
    "Reserved"
109
	"Reserved",
110
	"Reserved",
111
	"Reserved",
112
	"Reserved",
113
	"Reserved",
114
	"Reserved",
115
	"Reserved",
116
	"Reserved"
117 117
};
118 118
119 119
void isr_handler(registers_t r) {
120
    println("received interrupt: ");
121
    char s[3];
122
    int_to_ascii(r.int_no, s);
123
    println(s);
124
    println(exception_messages[r.int_no]);
120
	println("received interrupt: ");
121
	char s[3];
122
	int_to_ascii(r.int_no, s);
123
	println(s);
124
	println(exception_messages[r.int_no]);
125 125
}
126 126
127 127
void register_interrupt_handler(u8 n, isr_t handler) {
128
    interrupt_handlers[n] = handler;
128
	interrupt_handlers[n] = handler;
129 129
}
130 130
131 131
void irq_handler(registers_t r) {
132
    /* After every interrupt we need to send an EOI to the PICs
133
     * or they will not send another interrupt again */
134
    if (r.int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */
135
    port_byte_out(0x20, 0x20); /* master */
132
	/* After every interrupt we need to send an EOI to the PICs
133
	 * or they will not send another interrupt again */
134
	if (r.int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */
135
	port_byte_out(0x20, 0x20); /* master */
136 136
137
    /* Handle the interrupt in a more modular way */
138
    if (interrupt_handlers[r.int_no] != 0) {
139
        isr_t handler = interrupt_handlers[r.int_no];
140
        handler(r);
141
    }
137
	/* Handle the interrupt in a more modular way */
138
	if (interrupt_handlers[r.int_no] != 0) {
139
		isr_t handler = interrupt_handlers[r.int_no];
140
		handler(r);
141
	}
142 142
}
143 143
144 144
void irq_install() {
145
    /* Enable interruptions */
146
    asm volatile("sti");
147
    /* IRQ0: timer */
148
    init_timer(50);
149
    /* IRQ1: keyboard */
150
    init_keyboard();
145
	/* Enable interruptions */
146
	asm volatile("sti");
147
	/* IRQ0: timer */
148
	init_timer(50);
149
	/* IRQ1: keyboard */
150
	init_keyboard();
151 151
}

+ 21 - 21
cpu/ports.c

@ -4,34 +4,34 @@
4 4
 * Read a byte from the specified port
5 5
 */
6 6
u8 port_byte_in (u16 port) {
7
    u8 result;
8
    /* Inline assembler syntax
9
     * !! Notice how the source and destination registers are switched from NASM !!
10
     *
11
     * '"=a" (result)'; set '=' the C variable '(result)' to the value of register e'a'x
12
     * '"d" (port)': map the C variable '(port)' into e'd'x register
13
     *
14
     * Inputs and outputs are separated by colons
15
     */
16
    __asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
17
    return result;
7
	u8 result;
8
	/* Inline assembler syntax
9
	 * !! Notice how the source and destination registers are switched from NASM !!
10
	 *
11
	 * '"=a" (result)'; set '=' the C variable '(result)' to the value of register e'a'x
12
	 * '"d" (port)': map the C variable '(port)' into e'd'x register
13
	 *
14
	 * Inputs and outputs are separated by colons
15
	 */
16
	__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
17
	return result;
18 18
}
19 19
20 20
void port_byte_out (u16 port, u8 data) {
21
    /* Notice how here both registers are mapped to C variables and
22
     * nothing is returned, thus, no equals '=' in the asm syntax 
23
     * However we see a comma since there are two variables in the input area
24
     * and none in the 'return' area
25
     */
26
    __asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port));
21
	/* Notice how here both registers are mapped to C variables and
22
	 * nothing is returned, thus, no equals '=' in the asm syntax 
23
	 * However we see a comma since there are two variables in the input area
24
	 * and none in the 'return' area
25
	 */
26
	__asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port));
27 27
}
28 28
29 29
u16 port_word_in (u16 port) {
30
    u16 result;
31
    __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
32
    return result;
30
	u16 result;
31
	__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
32
	return result;
33 33
}
34 34
35 35
void port_word_out (u16 port, u16 data) {
36
    __asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port));
36
	__asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port));
37 37
}

+ 31 - 31
cpu/timer.c

@ -9,42 +9,42 @@ volatile u8 done = 0;
9 9
u32 countdown = 0;
10 10
11 11
static void timer_callback(registers_t regs) {
12
    tick++;
13
    if (!done && countdown) countdown--;
14
    if (countdown == 0) done = 1;
15
    UNUSED(regs);
12
	tick++;
13
	if (!done && countdown) countdown--;
14
	if (countdown == 0) done = 1;
15
	UNUSED(regs);
16 16
}
17 17
18 18
void init_timer(u32 freq) {
19
    cl_freq = freq;
20
    /* Install the function we just wrote */
21
    register_interrupt_handler(IRQ0, timer_callback);
19
	cl_freq = freq;
20
	/* Install the function we just wrote */
21
	register_interrupt_handler(IRQ0, timer_callback);
22 22
23
    /* Get the PIT value: hardware clock at 1193180 Hz */
24
    u32 divisor = 1193180 / freq;
25
    u8 low  = (u8)(divisor & 0xFF);
26
    u8 high = (u8)( (divisor >> 8) & 0xFF);
27
    /* Send the command */
28
    port_byte_out(0x43, 0x36); /* Command port */
29
    port_byte_out(0x40, low);
30
    port_byte_out(0x40, high);
23
	/* Get the PIT value: hardware clock at 1193180 Hz */
24
	u32 divisor = 1193180 / freq;
25
	u8 low  = (u8)(divisor & 0xFF);
26
	u8 high = (u8)( (divisor >> 8) & 0xFF);
27
	/* Send the command */
28
	port_byte_out(0x43, 0x36); /* Command port */
29
	port_byte_out(0x40, low);
30
	port_byte_out(0x40, high);
31 31
}
32 32
33 33
void delay(u32 ms) {
34
    if (cl_freq == 0) return; //Timer isn't initialized, so don't delay
35
    done = 0;
36
    countdown = ms * cl_freq / 1000;
37
    while (!done) { //TODO: Lower CPU clock speed to save some power
38
        __asm__("nop");
39
        __asm__("nop");
40
        __asm__("nop");
41
        __asm__("nop");
42
        __asm__("nop");
43
        __asm__("nop");
44
        __asm__("nop");
45
        __asm__("nop");
46
        __asm__("nop");
47
        __asm__("nop");
48
    }
49
    return;
34
	if (cl_freq == 0) return; //Timer isn't initialized, so don't delay
35
	done = 0;
36
	countdown = ms * cl_freq / 1000;
37
	while (!done) { //TODO: Lower CPU clock speed to save some power
38
		__asm__("nop");
39
		__asm__("nop");
40
		__asm__("nop");
41
		__asm__("nop");
42
		__asm__("nop");
43
		__asm__("nop");
44
		__asm__("nop");
45
		__asm__("nop");
46
		__asm__("nop");
47
		__asm__("nop");
48
	}
49
	return;
50 50
}

+ 3 - 3
cpu/types.h

@ -4,11 +4,11 @@
4 4
/* Instead of using 'chars' to allocate non-character bytes,
5 5
 * we will use these new type with no semantic meaning */
6 6
typedef unsigned int   u32;
7
typedef          int   s32;
7
typedef		  int   s32;
8 8
typedef unsigned short u16;
9
typedef          short s16;
9
typedef		  short s16;
10 10
typedef unsigned char  u8;
11
typedef          char  s8;
11
typedef		  char  s8;
12 12
13 13
#define low_16(address) (u16)((address) & 0xFFFF)
14 14
#define high_16(address) (u16)(((address) >> 16) & 0xFFFF)

+ 26 - 26
drivers/keyboard.c

@ -11,24 +11,24 @@ static u8 uppercase = 0;
11 11
12 12
#define SC_MAX 57
13 13
const char *sc_name[] = { "ERROR", "Esc", "1", "2", "3", "4", "5", "6",
14
    "7", "8", "9", "0", "-", "=", "Backspace", "Tab", "Q", "W", "E",
15
        "R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Lctrl",
16
        "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "`",
17
        "LShift", "\\", "Z", "X", "C", "V", "B", "N", "M", ",", ".",
18
        "/", "RShift", "Keypad *", "LAlt", "Spacebar"};
14
	"7", "8", "9", "0", "-", "=", "Backspace", "Tab", "Q", "W", "E",
15
		"R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Lctrl",
16
		"A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "`",
17
		"LShift", "\\", "Z", "X", "C", "V", "B", "N", "M", ",", ".",
18
		"/", "RShift", "Keypad *", "LAlt", "Spacebar"};
19 19
const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6',
20
    '7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y',
21
        'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G',
22
        'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V',
23
        'B', 'N', 'M', ',', '.', '/', '?', '*', '?', ' '};
20
	'7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y',
21
		'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G',
22
		'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V',
23
		'B', 'N', 'M', ',', '.', '/', '?', '*', '?', ' '};
24 24
25 25
const char sc_shift_below[] = { '?', '?', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '?', '?'};
26 26
const char sc_shift_middle[] = { ':', '"', '~', '?', '|'}; //0x27 to 0x2B
27 27
const char sc_shift_above[] = { '<', '>', '?', '?', '*', '?', ' '}; //0x33 to 0x39
28 28
29 29
static void keyboard_callback(registers_t regs) {
30
    /* The PIC leaves us the scancode in port 0x60 */
31
    u8 scancode = port_byte_in(0x60);
30
	/* The PIC leaves us the scancode in port 0x60 */
31
	u8 scancode = port_byte_in(0x60);
32 32
	u8 special = 1;
33 33
34 34
	if (scancode > SC_MAX)
@ -38,36 +38,36 @@ static void keyboard_callback(registers_t regs) {
38 38
		{
39 39
			uppercase = 0;
40 40
		}
41
    }
42
    else {
43
        if (scancode == LSHIFT || scancode == RSHIFT)
41
	}
42
	else {
43
		if (scancode == LSHIFT || scancode == RSHIFT)
44 44
		{
45 45
			uppercase = 1;
46 46
		}
47 47
		else
48 48
		{
49
            char letter = sc_ascii[(int)scancode];
49
			char letter = sc_ascii[(int)scancode];
50 50
			if (letter >= 65 && letter <= 90) {
51 51
				letter += 32 * !uppercase; //Remove 32 from letter(make it lower case) if uppercase is false
52 52
				special = 0;
53
            }
54
            else if (uppercase)
53
			}
54
			else if (uppercase)
55 55
			{
56
                if (scancode < 0x10)
56
				if (scancode < 0x10)
57 57
				{
58 58
					special = 0;
59
                    letter = sc_shift_below[scancode];
60
                }
59
					letter = sc_shift_below[scancode];
60
				}
61 61
				else if (scancode >= 0x27 && scancode <= 0x2B)
62 62
				{
63 63
					special = 0;
64
                    letter = sc_shift_middle[scancode - 0x27];
65
                }
64
					letter = sc_shift_middle[scancode - 0x27];
65
				}
66 66
				else if (scancode >= 0x33 && scancode <= 0x39)
67 67
				{
68 68
					special = 0;
69
                    letter = sc_shift_above[scancode - 0x33];
70
                }
69
					letter = sc_shift_above[scancode - 0x33];
70
				}
71 71
			}
72 72
			else if ((scancode >= 0x02 && scancode <= 0x0D) || (scancode >= 0x27 && scancode <= 0x29) ||
73 73
					 (scancode >= 0x33 && scancode <= 0x35) || scancode == 0x2B || scancode == 0x39) {
@ -83,8 +83,8 @@ static void keyboard_callback(registers_t regs) {
83 83
				keyboard_handler(letter);
84 84
			}
85 85
		}
86
    }
87
    UNUSED(regs);
86
	}
87
	UNUSED(regs);
88 88
}
89 89
90 90
void init_keyboard() {

+ 14 - 14
drivers/screen.c

@ -18,12 +18,12 @@ int get_offset_row(int offset);
18 18
int get_offset_col(int offset);
19 19
20 20
/**********************************************************
21
 * Public Kernel API functions                            *
21
 * Public Kernel API functions							  *
22 22
 **********************************************************/
23 23
24 24
void putpixel(int x, int y, u32 fg) {
25
    unsigned where = x*COLOR_BITS/8 + y*SCN_PITCH; //TODO: Should come from above function
26
    u8 *screen = (u8*) VIDEO_ADDRESS;
25
	unsigned where = x*COLOR_BITS/8 + y*SCN_PITCH; //TODO: Should come from above function
26
	u8 *screen = (u8*) VIDEO_ADDRESS;
27 27
28 28
	//TODO: Is there a way to set these all at once?
29 29
	for (int j = 0; j < COLOR_BITS/8; j++) {
@ -32,23 +32,23 @@ void putpixel(int x, int y, u32 fg) {
32 32
}
33 33
34 34
void fillrect(int x, int y, u32 fg, int w, int h) {
35
    unsigned where = x*COLOR_BITS/8 + y*SCN_PITCH;
36
    u8 *screen = (u8*) VIDEO_ADDRESS;
37
    int i, j;
35
	unsigned where = x*COLOR_BITS/8 + y*SCN_PITCH;
36
	u8 *screen = (u8*) VIDEO_ADDRESS;
37
	int i, j;
38 38
39
    for (i = 0; i < h; i++) {
40
        for (j = 0; j < w; j++) {
41
            //TODO: Is there a way to set these all at once?
39
	for (i = 0; i < h; i++) {
40
		for (j = 0; j < w; j++) {
41
			//TODO: Is there a way to set these all at once?
42 42
			for (int k = 0; k < COLOR_BITS/8; k++) {
43 43
				screen[where + (int)(j*COLOR_BITS/8) + k] = (fg >> k*8) & 255;
44 44
			}
45
        }
46
        where += SCN_PITCH;
47
    }
45
		}
46
		where += SCN_PITCH;
47
	}
48 48
}
49 49
50 50
void scroll_up(u8 lines) { //NOTE: Does not clear the bottom lines!
51
    memory_copy((u8 *)(VIDEO_ADDRESS + lines * SCN_PITCH), (u8 *)VIDEO_ADDRESS, (SCN_HEIGHT - lines) * SCN_PITCH);
51
	memory_copy((u8 *)(VIDEO_ADDRESS + lines * SCN_PITCH), (u8 *)VIDEO_ADDRESS, (SCN_HEIGHT - lines) * SCN_PITCH);
52 52
}
53 53
54 54
u32 color_to_pixel(Color_t color)
@ -66,7 +66,7 @@ u32 color_to_pixel(Color_t color)
66 66
}
67 67
68 68
/**********************************************************
69
 * Private kernel functions                               *
69
 * Private kernel functions								  *
70 70
 **********************************************************/
71 71
72 72

+ 35 - 35
kernel/kernel.c

@ -12,54 +12,54 @@
12 12
void generate_fractal(u16 x, u16 y, u16 w, u16 h);
13 13
14 14
void main() {
15
    isr_install();
16
    irq_install();
15
	isr_install();
16
	irq_install();
17 17
18
    setup_video();
18
	setup_video();
19 19
20
    set_background(0, 100, 100);
21
    clear_screen();
20
	set_background(0, 100, 100);
21
	clear_screen();
22 22
23
    print_centered(SCN_WIDTH, 8, "_______ _________ _______           _______  _______  _______ ");
24
    print_centered(SCN_WIDTH, 16,"(  ____ \\\\__   __/(  ____ \\|\\     /|(  ____ \\(  ___  )(  ____ \\");
25
    print_centered(SCN_WIDTH, 24,"| (    \\/   ) (   | (    \\/| )   ( || (    \\/| (   ) || (    \\/");
26
    print_centered(SCN_WIDTH, 32, "| (_____    | |   | (__    | |   | || (__    | |   | || (_____ ");
27
    print_centered(SCN_WIDTH, 40, "(_____  )   | |   |  __)   ( (   ) )|  __)   | |   | |(_____  )");
28
    print_centered(SCN_WIDTH, 48, "      ) |   | |   | (       \\ \\_/ / | (      | |   | |      ) |");
29
    print_centered(SCN_WIDTH, 56, "/\\____) |   | |   | (____/\\  \\   /  | (____/\\| (___) |/\\____) |");
30
    print_centered(SCN_WIDTH, 64, "\\_______)   )_(   (_______/   \\_/   (_______/(_______)\\_______)");
31
    set_offset(0, 80);
23
	print_centered(SCN_WIDTH, 8, "_______ _________ _______           _______  _______  _______ ");
24
	print_centered(SCN_WIDTH, 16,"(  ____ \\\\__   __/(  ____ \\|\\     /|(  ____ \\(  ___  )(  ____ \\");
25
	print_centered(SCN_WIDTH, 24,"| (    \\/   ) (   | (    \\/| )   ( || (    \\/| (   ) || (    \\/");
26
	print_centered(SCN_WIDTH, 32, "| (_____    | |   | (__    | |   | || (__    | |   | || (_____ ");
27
	print_centered(SCN_WIDTH, 40, "(_____  )   | |   |  __)   ( (   ) )|  __)   | |   | |(_____  )");
28
	print_centered(SCN_WIDTH, 48, "      ) |   | |   | (       \\ \\_/ / | (      | |   | |      ) |");
29
	print_centered(SCN_WIDTH, 56, "/\\____) |   | |   | (____/\\  \\   /  | (____/\\| (___) |/\\____) |");
30
	print_centered(SCN_WIDTH, 64, "\\_______)   )_(   (_______/   \\_/   (_______/(_______)\\_______)");
31
	set_offset(0, 80);
32 32
33
    generate_fractal(SCN_WIDTH - 64 - 8, 8, 64, 64);
33
	generate_fractal(SCN_WIDTH - 64 - 8, 8, 64, 64);
34 34
35
	//    if (!init_floppy()) {
36
    //    println("WARNING: This type of floppy drive is not supported by the system.");
37
    //}
35
	//	  if (!init_floppy()) {
36
	//	  println("WARNING: This type of floppy drive is not supported by the system.");
37
	//}
38 38
39
    println("STEVEOS V0.0.2");
40
    println("WRITTEN BY STEPHEN DOWNWARD");
41
    println("TYPE \"HELP\" FOR HELP.");
42
    print("> ");
39
	println("STEVEOS V0.0.2");
40
	println("WRITTEN BY STEPHEN DOWNWARD");
41
	println("TYPE \"HELP\" FOR HELP.");
42
	print("> ");
43 43
44
    register_commands();
44
	register_commands();
45 45
}
46 46
47 47
//Mandelbrot Generator
48 48
void generate_fractal(u16 x, u16 y, u16 w, u16 h) {
49
    for(int i = 0; i < w; i++) {
50
        for (int j = 0; j < h; j++) {
51
            double Zr = 0;
52
            double Zrt = 0; //Temp
53
            double Zi = 0;
49
	for(int i = 0; i < w; i++) {
50
		for (int j = 0; j < h; j++) {
51
			double Zr = 0;
52
			double Zrt = 0; //Temp
53
			double Zi = 0;
54 54
55
            double Cr = ((double)i/w)*3 - 2;
56
            double Ci = ((double)j/h)*3 - 1.5;
55
			double Cr = ((double)i/w)*3 - 2;
56
			double Ci = ((double)j/h)*3 - 1.5;
57 57
58
            int numIterations = 0;
59
            u8 painted = 0;
60
            while (numIterations < 255) {
61
                numIterations++;
62
                Zrt = Zr * Zr + Cr - (Zi * Zi);
58
			int numIterations = 0;
59
			u8 painted = 0;
60
			while (numIterations < 255) {
61
				numIterations++;
62
				Zrt = Zr * Zr + Cr - (Zi * Zi);
63 63
				Zi = 2 * Zi * Zr + Ci;
64 64
				Zr = Zrt;
65 65
				

+ 6 - 6
libc/mem.c

@ -1,13 +1,13 @@
1 1
#include "mem.h"
2 2
3 3
void memory_copy(u8 *source, u8 *dest, int nbytes) {
4
    int i;
5
    for (i = 0; i < nbytes; i++) {
6
        *(dest + i) = *(source + i);
7
    }
4
	int i;
5
	for (i = 0; i < nbytes; i++) {
6
		*(dest + i) = *(source + i);
7
	}
8 8
}
9 9
10 10
void memory_set(u8 *dest, u8 val, u32 len) {
11
    u8 *temp = (u8 *)dest;
12
    for ( ; len != 0; len--) *temp++ = val;
11
	u8 *temp = (u8 *)dest;
12
	for ( ; len != 0; len--) *temp++ = val;
13 13
}

+ 33 - 33
libc/string.c

@ -4,76 +4,76 @@
4 4
 * K&R implementation
5 5
 */
6 6
void int_to_ascii(int n, char str[]) {
7
    int i, sign;
8
    if ((sign = n) < 0) n = -n;
9
    i = 0;
10
    do {
11
        str[i++] = n % 10 + '0';
12
    } while ((n /= 10) > 0);
7
	int i, sign;
8
	if ((sign = n) < 0) n = -n;
9
	i = 0;
10
	do {
11
		str[i++] = n % 10 + '0';
12
	} while ((n /= 10) > 0);
13 13
14
    if (sign < 0) str[i++] = '-';
15
    str[i] = '\0';
14
	if (sign < 0) str[i++] = '-';
15
	str[i] = '\0';
16 16
17
    reverse(str);
17
	reverse(str);
18 18
}
19 19
20 20
/* K&R */
21 21
void reverse(char s[]) {
22
    int c, i, j;
23
    for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
24
        c = s[i];
25
        s[i] = s[j];
26
        s[j] = c;
27
    }
22
	int c, i, j;
23
	for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
24
		c = s[i];
25
		s[i] = s[j];
26
		s[j] = c;
27
	}
28 28
}
29 29
30 30
/* K&R */
31 31
int strlen(char s[]) {
32
    int i = 0;
33
    while (s[i] != '\0') ++i;
34
    return i;
32
	int i = 0;
33
	while (s[i] != '\0') ++i;
34
	return i;
35 35
}
36 36
37 37
void append(char s[], char n) {
38
    int len = strlen(s);
39
    s[len] = n;
40
    s[len+1] = '\0';
38
	int len = strlen(s);
39
	s[len] = n;
40
	s[len+1] = '\0';
41 41
}
42 42
43 43
void backspace(char s[]) {
44
    int len = strlen(s);
45
    s[len-1] = '\0';
44
	int len = strlen(s);
45
	s[len-1] = '\0';
46 46
}
47 47
48 48
/* K&R
49 49
 * Returns <0 if s1<s2, 0 if s1==s2, >0 if s1>s2 */
50 50
int strcmp(char s1[], char s2[]) {
51
    int i;
52
    for (i = 0; s1[i] == s2[i]; i++) {
53
        if (s1[i] == '\0') return 0;
54
    }
55
    return s1[i] - s2[i];
51
	int i;
52
	for (i = 0; s1[i] == s2[i]; i++) {
53
		if (s1[i] == '\0') return 0;
54
	}
55
	return s1[i] - s2[i];
56 56
}
57 57
58 58
//New stuff
59 59
60 60
//Splits a string into 2 at a separator
61 61
void strsplit(char *orig, char separator, char *a, char *b) {
62
    int found = 0;
63
    for(int i = 0; i < strlen(orig); i++) {
62
	int found = 0;
63
	for(int i = 0; i < strlen(orig); i++) {
64 64
		if (orig[i] == separator && found == 0) found = i + 1; //+1 for the seperator char
65 65
		if (found > 0) {
66 66
			b[i - found] = orig[i];
67 67
		} else {
68 68
			a[i] = orig[i];
69 69
		}
70
    }
70
	}
71 71
}
72 72
73 73
void tolowercase(char *in) {
74
    for(int i = 0; i < strlen(in); i++) {
74
	for(int i = 0; i < strlen(in); i++) {
75 75
		if(in[i] >= 65 && in[i] <= 90) {
76 76
			in[i] += 32;
77 77
		}
78
    }
78
	}
79 79
}

+ 14 - 14
programs/texteditor.c

@ -4,28 +4,28 @@
4 4
#include "../drivers/screen.h"
5 5
6 6
void gen_padding(char *menu) {
7
    print("=");
8
    for(u8 i = 0; i < strlen(menu); i++) {
9
        if (menu[i] != '|')
10
            print("=");
11
        else
12
            print("|");
13
    }
14
    println("=");
7
	print("=");
8
	for(u8 i = 0; i < strlen(menu); i++) {
9
		if (menu[i] != '|')
10
			print("=");
11
		else
12
			print("|");
13
	}
14
	println("=");
15 15
}
16 16
17 17
void gen_menu() {
18
    //Top bar
18
	//Top bar
19 19
	Color_t red;
20 20
	red.r = 255;
21 21
	fillrect(0, 0, color_to_pixel(red), SCN_WIDTH, 9);
22
	print("File    Edit    Exit");
22
	print("File	   Edit	   Exit");
23 23
}
24 24
25 25
void editor() {
26
    //Clear screen
27
    clear_screen();
26
	//Clear screen
27
	clear_screen();
28 28
29
    //Menu setup
30
    gen_menu();
29
	//Menu setup
30
	gen_menu();
31 31
}

+ 7 - 7
util/bitmap.c

@ -1,14 +1,14 @@
1 1
#include "bitmap.h"
2 2
3 3
struct bitmap {
4
    int height;
5
    int width;
6
    char *R, *B, *G;
4
	int height;
5
	int width;
6
	char *R, *B, *G;
7 7
};
8 8
9 9
/*bitmap get_Tux() {
10
    struct bitmap tux;
11
    tux.height = 860;
12
    tux.width = 712;
13
    *tux.R = ;
10
	struct bitmap tux;
11
	tux.height = 860;
12
	tux.width = 712;
13
	*tux.R = ;
14 14
}*/

+ 16 - 14
util/commands.c

@ -3,29 +3,30 @@
3 3
#include "../drivers/screen.h"
4 4
#include "../libc/function.h"
5 5
#include "../libc/string.h"
6
#include "../programs/texteditor.h"
6 7
7 8
void help(char *args) {
8
    UNUSED(args);
9
    println("Not implemented yet :( you have to pester stephen");
9
	UNUSED(args);
10
	println("Not implemented yet :( you have to pester stephen");
10 11
}
11 12
12 13
void echo(char *args) {
13
    println(args);
14
	println(args);
14 15
}
15 16
16 17
void clear(char *args) {
17
    UNUSED(args);
18
    clear_screen();
18
	UNUSED(args);
19
	clear_screen();
19 20
}
20 21
21 22
void change_bg (char *args) {
22
    set_background((args[0] - '0' ) * 28, (args[1] - '0') * 28, (args[2] - '0') * 28);
23
	set_background((args[0] - '0' ) * 28, (args[1] - '0') * 28, (args[2] - '0') * 28);
23 24
}
24 25
25 26
void halt_cpu(char *args) {
26
    UNUSED(args);
27
    println("Shutting down the CPU. Goodbye.");
28
    __asm__ __volatile__("hlt");
27
	UNUSED(args);
28
	println("Shutting down the CPU. Goodbye.");
29
	__asm__ __volatile__("hlt");
29 30
}
30 31
31 32
void video_debug(char *args) {
@ -81,10 +82,11 @@ void video_debug(char *args) {
81 82
}
82 83
83 84
void register_commands() {
84
    register_command("help", help);
85
    register_command("echo", echo);
86
    register_command("clear", clear);
87
    register_command("bgc", change_bg);
88
    register_command("halt", halt_cpu);
85
	register_command("help", help);
86
	register_command("echo", echo);
87
	register_command("clear", clear);
88
	register_command("bgc", change_bg);
89
	register_command("halt", halt_cpu);
89 90
	register_command("vinfo", video_debug);
91
	register_command("edit", editor);
90 92
}

+ 99 - 99
util/font.c

@ -4,125 +4,125 @@
4 4
#include "../util/types.h"
5 5
6 6
u16 characters[26 * 8 + 31 * 8 + 16*8] = {
7
    24,24,0,24,60,60,126,126,
8
    0,0,0,0,108,108,108,108,
9
    108,254,254,108,108,254,254,108,
10
    16,124,124,16,8,124,124,16,
11
    198,206,28,56,112,224,198,6,
12
    16,124,64,124,64,64,124,16,
13
    0,0,0,0,6,6,6,6,
14
    24,30,14,6,6,14,30,24,
15
    6,30,28,24,24,28,30,6,
16
    146,84,56,254,56,84,146,16,
17
    0,24,24,126,126,24,24,0,
18
    28,56,48,0,0,0,0,0,
19
    0,0,0,252,252,0,0,0,
20
    14,14,14,0,0,0,0,0,
21
    6,14,28,56,112,224,192,0,
22
    254,254,206,222,246,230,254,254,
23
    254,254,48,48,48,62,60,56,
24
    254,254,28,56,118,230,254,254,
25
    254,254,192,254,254,192,254,254,
26
    48,48,48,254,254,54,54,54,
27
    254,254,198,192,254,6,254,254,
28
    254,254,198,254,254,6,254,254,
29
    48,48,48,48,48,48,62,62,
30
    124,238,198,254,124,198,238,124,
31
    192,192,254,254,198,198,254,254,
32
    24,24,0,0,0,0,24,24,
33
    12,28,56,48,0,0,48,48,
34
    48,56,28,14,14,28,56,48,
35
    0,0,254,254,0,254,254,0,
36
    24,56,112,224,224,112,56,24,
37
    24,24,0,120,120,96,120,120,
38
    254,254,6,246,246,198,254,254,
39
    198,198,254,254,198,238,124,56,
40
    62,126,102,126,126,102,126,62,
41
    126,126,6,6,6,6,126,126,
42
    62,126,230,198,198,230,126,62,
43
    254,254,6,30,30,6,254,254,
44
    6,6,126,126,6,6,254,254,
45
    254,254,198,246,246,6,254,254,
46
    198,198,198,254,254,198,198,198,
47
    126,126,24,24,24,24,126,126,
48
    62,62,54,54,48,48,48,48,
49
    102,118,62,30,30,62,118,102,
50
    62,62,6,6,6,6,6,6,
51
    198,198,198,214,254,254,238,198,
52
    198,198,246,246,222,222,198,198,
53
    254,254,198,198,198,198,254,254,
54
    6,6,62,126,102,102,126,62,
55
    62,126,246,246,198,198,254,254,
56
    230,118,62,126,102,102,126,62,
57
    126,126,112,56,28,14,126,126,
58
    24,24,24,24,24,24,126,126,
59
    254,254,198,198,198,198,198,198,
60
    24,60,126,102,102,102,102,102,
61
    198,238,254,254,214,198,198,198,
62
    198,238,124,56,56,124,238,198,
63
    24,24,24,24,60,126,102,102,
64
    126,126,12,28,56,48,126,126,
65
    30,30,6,6,6,6,30,30,
66
    192,224,112,56,28,14,6,0,
67
    30,30,24,24,24,24,30,30,
68
    0,0,0,132,204,252,120,48,
69
    254,254,0,0,0,0,0,0,
70
    0,0,0,0,0,12,14,6,
71
    192,254,254,198,198,254,254,192,
72
    62,126,102,102,126,62,6,6,
73
    62,62,6,62,62,0,0,0,
74
    254,254,246,254,254,192,192,192,
75
    254,254,6,246,246,198,254,254,
76
    24,126,126,24,216,216,248,248,
77
    126,64,126,126,102,102,126,126,
78
    102,102,126,126,6,6,6,6,
79
    6,6,6,6,6,0,6,6
7
	24,24,0,24,60,60,126,126,
8
	0,0,0,0,108,108,108,108,
9
	108,254,254,108,108,254,254,108,
10
	16,124,124,16,8,124,124,16,
11
	198,206,28,56,112,224,198,6,
12
	16,124,64,124,64,64,124,16,
13
	0,0,0,0,6,6,6,6,
14
	24,30,14,6,6,14,30,24,
15
	6,30,28,24,24,28,30,6,
16
	146,84,56,254,56,84,146,16,
17
	0,24,24,126,126,24,24,0,
18
	28,56,48,0,0,0,0,0,
19
	0,0,0,252,252,0,0,0,
20
	14,14,14,0,0,0,0,0,
21
	6,14,28,56,112,224,192,0,
22
	254,254,206,222,246,230,254,254,
23
	254,254,48,48,48,62,60,56,
24
	254,254,28,56,118,230,254,254,
25
	254,254,192,254,254,192,254,254,
26
	48,48,48,254,254,54,54,54,
27
	254,254,198,192,254,6,254,254,
28
	254,254,198,254,254,6,254,254,
29
	48,48,48,48,48,48,62,62,
30
	124,238,198,254,124,198,238,124,
31
	192,192,254,254,198,198,254,254,
32
	24,24,0,0,0,0,24,24,
33
	12,28,56,48,0,0,48,48,
34
	48,56,28,14,14,28,56,48,
35
	0,0,254,254,0,254,254,0,
36
	24,56,112,224,224,112,56,24,
37
	24,24,0,120,120,96,120,120,
38
	254,254,6,246,246,198,254,254,
39
	198,198,254,254,198,238,124,56,
40
	62,126,102,126,126,102,126,62,
41
	126,126,6,6,6,6,126,126,
42
	62,126,230,198,198,230,126,62,
43
	254,254,6,30,30,6,254,254,
44
	6,6,126,126,6,6,254,254,
45
	254,254,198,246,246,6,254,254,
46
	198,198,198,254,254,198,198,198,
47
	126,126,24,24,24,24,126,126,
48
	62,62,54,54,48,48,48,48,
49
	102,118,62,30,30,62,118,102,
50
	62,62,6,6,6,6,6,6,
51
	198,198,198,214,254,254,238,198,
52
	198,198,246,246,222,222,198,198,
53
	254,254,198,198,198,198,254,254,
54
	6,6,62,126,102,102,126,62,
55
	62,126,246,246,198,198,254,254,
56
	230,118,62,126,102,102,126,62,
57
	126,126,112,56,28,14,126,126,
58
	24,24,24,24,24,24,126,126,
59
	254,254,198,198,198,198,198,198,
60
	24,60,126,102,102,102,102,102,
61
	198,238,254,254,214,198,198,198,
62
	198,238,124,56,56,124,238,198,
63
	24,24,24,24,60,126,102,102,
64
	126,126,12,28,56,48,126,126,
65
	30,30,6,6,6,6,30,30,
66
	192,224,112,56,28,14,6,0,
67
	30,30,24,24,24,24,30,30,
68
	0,0,0,132,204,252,120,48,
69
	254,254,0,0,0,0,0,0,
70
	0,0,0,0,0,12,14,6,
71
	192,254,254,198,198,254,254,192,
72
	62,126,102,102,126,62,6,6,
73
	62,62,6,62,62,0,0,0,
74
	254,254,246,254,254,192,192,192,
75
	254,254,6,246,246,198,254,254,
76
	24,126,126,24,216,216,248,248,
77
	126,64,126,126,102,102,126,126,
78
	102,102,126,126,6,6,6,6,
79
	6,6,6,6,6,0,6,6
80 80
};
81 81
82 82
void draw_char(int x, int y, char c, u32 fg) {
83 83
	unsigned where = x*COLOR_BITS/8 + y*SCN_PITCH;
84 84
	u8 *screen = (u8 *) VIDEO_ADDRESS;
85
    if (c == 124) { //Custom code for |
86
        for(int r = 0; r < 8; r++) {//Rows
87
            putpixel(x + 3, y - r, fg); //TODO: CHANGE THIS
88
            putpixel(x + 4, y - r, fg); //TODO: CHANGE THIS
89
        }
90
    }
91
    else {
92
        if (c >= 106) {
93
            c -= 32;
94
        }
95
        //We now know c is a letter we have. Subtract 65 to get a number we can use in the above array.
96
        c -= 33;
97
        for(int r = 0; r < 8; r++) {//Rows
98
            uint16 row = characters[c * 8 + r];
99
            for (int i = 0; i < 8; i++) {
100
                if (row&(1 << i)) {
85
	if (c == 124) { //Custom code for |