summaryrefslogtreecommitdiff
path: root/src/boot/stage2_pm_functions.asm
blob: f3c348b72d57c4c6245e88bbc050a7db667680a8 (plain)
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
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:
	lodsb
	cmp al, 0
	je .fini
	call pm_print_char
	jmp .loop
.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

; IN dx: hex value to print	
pm_print_hex:
	push bx
	push si
	mov si, PM_HEX_TEMPLATE
	mov bx, dx
	shr bx, 12
	mov bx, [PM_HEXABET+bx]
	mov [PM_HEX_TEMPLATE+2], bl
	mov bx, dx
	and bx, 0x0FFF
	shr bx, 8
	mov bx, [PM_HEXABET+bx]
	mov [PM_HEX_TEMPLATE+3], bl
	mov bx, dx
	and bx, 0x00FF
	shr bx, 4
	mov bx, [PM_HEXABET+bx]
	mov [PM_HEX_TEMPLATE+4], bl
	mov bx, dx
	and bx, 0x000F
	mov bx, [PM_HEXABET+bx]
	mov [PM_HEX_TEMPLATE+5], bl
	call pm_print_string
	pop si
	pop bx
	ret

inc_cursor:
	push eax
	mov ax, [CURSOR_X]
	inc ax
	mov [CURSOR_X], ax
	cmp ax, VIDEO_COLS
	jl .fini
	mov [CURSOR_X], word 1
	mov ax, [CURSOR_Y]
	inc ax
	mov [CURSOR_Y], ax
	cmp ax, VIDEO_ROWS
	jl .fini
	; TODO: scoll one line, for now restart on top
	mov [CURSOR_Y], word 0
.fini:
	call update_vga_cursor
	pop eax
	ret
	
; update the VGA cursor on screen
update_vga_cursor:
	push eax
	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
	pop eax
	ret

; read cursor from hardware
read_hardware_vga_cursor:
	push eax
	push ebx
	push ecx
	push edx
	xor eax, eax
	xor ebx, ebx
	mov al, 0eh
	mov dx, 3d4h
	out dx, al
	mov dx, 3d5h
	in al, dx
	mov bh, al
	mov al, 0fh
	mov dx, 3d4h
	out dx, al
	mov dx, 3d5h
	in al, dx
	mov bl, al
	mov ax, bx
	mov edx, 0
	mov cx, VIDEO_COLS
	div cx
	mov [CURSOR_X], dx
	mov [CURSOR_Y], ax 
	pop edx
	pop ecx
	pop ebx
	pop eax
	ret

PM_HEX_TEMPLATE:
	db '0x???? ', 0

PM_HEXABET:
	db '0123456789ABCDEF'