summaryrefslogtreecommitdiff
path: root/kernel.asm
blob: 490273c655dbfb7bb3f0b4216d5b9fe48e4ab004 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
section .text
align 4
global kmain
global interrupt_handler
extern idt_init
extern pio_read
extern pio_write

interrupt_handler:
    mov ebx, [esp + 34]
    shr ebx, 16
    cmp ebx, 0x21
    je .int21

    jmp .end

.int21:

    cmp ah, 0x1
    je .int21.kprint
    jmp .end

.int21.kprint:
    ;sub esp, 4
    ;mov [esp - 4], bx

    ;shr bx, 8
    ;push word bx

    ;mov bx, [esp - 4]
    ;and bx, 0xff
    ;push bx

    ;call screen_gotoxy
    ;add esp, 8

    push edx
    call kprint
    add esp, 4

.end:
    ret

cursor_move:
    push ebp
    mov ebp, esp

    sub ebp, 4
    call screen_getxy
    mov [ebp - 4], eax

    push 0x3D4
    push 14
    call pio_write

    mov ebx, [ebp + 4]
    shr ebx, 8
    push 0x3D5
    push word [ebx]
    call pio_write

    push 0x3D4
    push 15
    call pio_write

    mov ebx, [ebp + 4]
    push 0x3D5
    push word [ebx]
    call pio_write

    add ebp, 4
    leave
    ret

screen_fill:
    ; = purpose
    ; Fills the screen with a character and color
    ;
    ; = stack arguments (order of use)
    ; push ' '      ; character
    ; push 0x07     ; color attribute

    push ebp
    mov ebp, esp

    xor eax, eax                ; clear eax
    mov eax, [ebp + 8]          ; get character
    shl eax, 8                  ; shift character into MSB
    or eax, [ebp + 12]          ; set color attribute

    mov ecx, CONSOLE_SIZE       ; use entire screen
    mov edi, screen_buffer      ; destination = screen_buffer
    cld                         ; will increment esi and edi
    rep stosw                   ; char+color -> screen_buffer

    mov esp, ebp
    pop ebp

    ret

screen_refresh:
    push ebp
    mov ebp, esp
    pusha

    mov ecx, CONSOLE_SIZE       ; use entire screen
    mov esi, screen_buffer      ; source = screen_buffer
    mov edi, VIDEO_RAM          ; destination = video RAM
    cld                         ; will increment esi and edi
    rep movsw                   ; char+color -> screen_buffer

    popa
    mov esp, ebp
    pop ebp
    ret

screen_gotoxy:
    push ebp
    mov ebp, esp
    pusha

    ; y * width + x
    mov ebx, CONSOLE_W * 2
    mov eax, [ebp + 12]
    mul ebx
    add eax, [ebp + 8]
    mov [screen_pos], eax

    popa
    leave
    ret

screen_getxy:
    push ebp
    mov ebp, esp

    mov eax, [screen_pos]

    leave
    ret

screen_updatexy:
    push ebp
    mov ebp, esp

    add word [screen_pos], 2

    cmp word [screen_pos], CONSOLE_SIZE
    call screen_scroll_up

    leave
    ret

screen_scroll_up:
    push ebp
    mov ebp, esp

    nop

    leave
    ret

screen_scroll_down:
    push ebp
    mov ebp, esp

    nop

    leave
    ret


kprint:
    ; = purpose
    ; Writes a buffer to the screen
    ;
    ; = globals
    ; kprint_delay:   if != 0; echo slowly
    ;
    ; = stack arguments (order of use)
    ; push buffer

    push ebp
    mov ebp, esp

    xor ebx, ebx
    xor esi, esi
    xor edi, edi

    mov esi, [ebp + 8]          ; source buffer
    mov edi, screen_buffer      ; output to screen buffer
    mov ebx, [screen_pos]       ; get current screen position
    add edi, ebx                ; move to current screen position
    mov ecx, 0xff               ; delay counter

.write:

    cmp byte [kprint_delay], 0  ; determine if we want a delay
    je .nodelay                 ;   if kprint_nodelay == 0:
                                ;       nodelay()
                                ;   else:
                                ;       delay()

.delay:
    dec ecx                     ; while ecx != 0: ecx--
    call screen_refresh
    jne .delay

.nodelay:
    mov ebx, [esi]              ; get value from source buffer
    mov [edi], bl               ; write value to screen buffer
    inc esi                     ; next char in source buffer
    add edi, 2                  ; skip over screen attribute byte
    call screen_updatexy        ; update screen_pos

    cmp bl, 0                   ; if ch != 0: write
    jne .write

    call screen_refresh         ; dump screen buffer to video ram

    leave
    ret

kputc:
    push ebp
    mov ebp, esp

    mov esi, [screen_pos]
    mov edi, screen_buffer
    add edi, esi

    mov [edi], dl
    call screen_updatexy
    call screen_refresh

    leave
    ret

kprintnl:
    push ebp
    mov ebp, esp

    nop

    leave
    ret

kmain:
    push ebp
    mov ebp, esp

    mov byte [screen_pos], 2    ; Initialize screen position
    ;call cursor_move

    call idt_init

                                ; Fill screen with
    push ' '               ; spaces &&
    push 0x07                   ; white forground on blue background
    call screen_fill            ; fill the screen buffer
    call screen_refresh         ; dump screen buffer to video ram

    ;push 12
    ;push 30
    ;call screen_gotoxy

    ;mov byte [kprint_delay], 1  ; tell kprint to delay writes
    push message                ; push message address as argument
    call kprint                 ; print message

    call kprintnl

    mov dl, 'A'
    call kputc

    mov word [VIDEO_RAM + CONSOLE_SIZE - 6], \
                0x4F << 8 | 'I' ; END OF MAIN MARKER
    ;mov ah, 1
    ;mov bh, 2
    ;mov bl, 2
    ;mov edx, message2
    ;int 21h ; here goes nothing

    mov word [VIDEO_RAM + CONSOLE_SIZE - 6], \
                0x2F << 8 | 'I' ; END OF MAIN MARKER

    mov word [VIDEO_RAM + CONSOLE_SIZE - 4], \
                0x2F << 8 | 'K' ; END OF MAIN MARKER

    mov esp, ebp
    pop ebp
    ret

section .data
%include 'constants.asm'

message: db 'Kernel programming is fun!', 0
message2: db 'This is a test.', 0

section .bss
kprint_delay: resb 1
screen_pos: resd 1
screen_buffer: resb CONSOLE_SIZE
screen_buffer_end: