summaryrefslogtreecommitdiff
path: root/src/stage2_functions.asm
blob: 2954d6274623897f2e02810fc62032423c7d4364 (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
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
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

; IN dx: hex value to print	
pm_print_hex:
	push bx
	push si
	mov si, HEX_TEMPLATE
	mov bx, dx
	shr bx, 12
	mov bx, [HEXABET+bx]
	mov [HEX_TEMPLATE+2], bl
	mov bx, dx
	and bx, 0x0FFF
	shr bx, 8
	mov bx, [HEXABET+bx]
	mov [HEX_TEMPLATE+3], bl
	mov bx, dx
	and bx, 0x00FF
	shr bx, 4
	mov bx, [HEXABET+bx]
	mov [HEX_TEMPLATE+4], bl
	mov bx, dx
	and bx, 0x000F
	mov bx, [HEXABET+bx]
	mov [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 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 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

; check whether the end of the loaded image contains in fact the magic
; string (avoid truncation of image)
check_magic:
	push ebx
	push ecx
	push edx
	push esi
	push edi
	mov eax, NOF_LOAD_SECTORS	; number of 512-byte sectors
	shl eax, 9			; 512 bytes per sector
	mov edx, 0x7e00			; offset of stage 2
	add edx, eax
	sub edx, MAGICLEN		; subtract the length of the magic string
	mov esi, edx			; now use edx as first string address to compare to
	mov edi, COMPARE_MAGIC		; position of second string
	mov ecx, MAGICLEN		; length of the magic string
	repe cmpsb
	jne MAGIC_MISMATCH
	jmp MAGIC_OK
MAGIC_MISMATCH:
	mov si, MAGIC_OK_MSG
	call pm_print_string
	call pm_print_newline
	xor eax, eax
	jmp MAGIC_END
MAGIC_OK:
	mov si, MAGIC_NOT_OK_MSG
	call pm_print_string
	call pm_print_newline
	xor eax, eax
	mov eax, 1
MAGIC_END:
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	ret

COMPARE_MAGIC:
db "ABAOSMAGIC", 0
MAGICLEN equ $ - COMPARE_MAGIC

MAGIC_NOT_OK_MSG:
db "Magic signature found", 0

MAGIC_OK_MSG:
db "Magic signature not found!", 0