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
|
VIDEO_MEMORY equ 0xb8000
VIDEO_COLS equ 80
VIDEO_ROWS equ 25
CURSOR_X:
dw 0
CURSOR_Y:
dw 0
pm_print_newline:
push eax
mov [CURSOR_X], word 0
mov ax, [CURSOR_Y]
inc ax
mov [CURSOR_Y], ax
pop eax
call update_vga_cursor
ret
; IN si
pm_print_string:
push eax
_loop_pm_print_string:
lodsb
cmp al, 0
je pm_print_string_fini
call pm_print_char
jmp _loop_pm_print_string
pm_print_string_fini:
pop eax
ret
; IN al: character to print
pm_print_char:
push edx
push ecx
push ebx
push eax
mov ax, [CURSOR_Y]
mov cl, VIDEO_COLS
mul cl
mov bx, [CURSOR_X]
add ax, bx
shl ax, 1
mov edx, VIDEO_MEMORY
add dx, ax
pop eax
mov ah, 0x07
mov [edx], ax
pop ebx
pop ecx
pop edx
call inc_cursor
ret
inc_cursor:
push eax
mov ax, [CURSOR_X]
inc ax
mov [CURSOR_X], ax
cmp ax, VIDEO_COLS
jl inc_cursor_fini
mov [CURSOR_X], word 1
mov ax, [CURSOR_Y]
inc ax
mov [CURSOR_Y], ax
cmp ax, VIDEO_ROWS
jl inc_cursor_fini
; TODO: scoll one line, for now restart on top
mov [CURSOR_Y], word 0
inc_cursor_fini:
call update_vga_cursor
pop eax
ret
; update the VGA cursor on screen
update_vga_cursor:
push ebx
push ecx
push edx
mov al, [CURSOR_Y]
mov cl, VIDEO_COLS
mul cl
mov bx, ax
movzx ax, [CURSOR_X]
add bx, ax
mov cx, bx
;cursor LOW port to vga INDEX register
mov al, 0fh ;Cursor Location Low Register --
mov dx, 3d4h ;VGA port 3D4h
out dx, al
mov ax, cx ;restore 'postion' back to AX
mov dx, 3d5h ;VGA port 3D5h
out dx, al ;send to VGA hardware
;cursor HIGH port to vga INDEX register
mov al, 0eh
mov dx, 3d4h ;VGA port 3D4h
out dx, al
mov ax, cx ;restore 'position' back to AX
shr ax, 8 ;get high byte in 'position'
mov dx, 3d5h ;VGA port 3D5h
out dx, al ;send to VGA hardware
pop edx
pop ecx
pop ebx
ret
|