-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvga.asm
More file actions
210 lines (173 loc) · 4.79 KB
/
vga.asm
File metadata and controls
210 lines (173 loc) · 4.79 KB
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
;the vga driver code needs to be segregated to this file
;it's actually not "setting" vga mode 3. It's just using the already set up mode 3 that every 286 and later bios uses
vgaSetupText3h:
mov ax, 0B800h
mov es, ax
mov di, 0
mov cx, 2048
vgaSetupText3hLoop:
;write a null character to the character byte
mov al, 0
mov [es:di], al
;increment address counter
inc di
;write to attribute byte. black background. white foreground
mov al, 00001111b
mov [es:di], al
;increment address counter, decrement loop counter
inc di
dec cx
cmp cx, 0
ja vgaSetupText3hLoop
;don't forget to zero out the cursor and set it
mov cl, 0
call setCurX
mov cl, 0
call setCurY
ret
;updates the cursor on the screen to the correct spot
vgaCursorPosToVram:
;calculate the correct line number from cursorY
mov al, [ds:cursorY]
mov ah, 0
mov bx, 00A0h
mul bx
mov di, ax
;add the column number in cursorX to di so that the character prints to the correct column
mov al, [ds:cursorX]
mov ah, 0
mov bx, 2
mul bx
add di, ax
;make it so that the vga cursor reflects these values
call setCursorPosBasedOnData
ret
;parameters: cl = color. ax = char
vgaPrintChar:
;print the character byte
mov [es:di], al
inc di
;print the color byte
mov al, cl
mov [es:di], al
inc di
ret
vgaIncrementCursor:
;check if the character line count this has exceeded 80
mov cl, [ds:cursorX]
cmp cl, 79
jae makeNewLine
;if count not exceeded, increment count by 1
inc cl
mov [ds:cursorX], cl
ret
;if count exceeded, set cursorX to zero then increment cursorY
makeNewLine:
push bx
call textModeNewLine
pop bx
ret
vgaDecrementCursor:
mov cl, [ds:cursorX]
cmp cl, 0
je fuck
dec cl
mov [ds:cursorX], cl
ret
;set cursorx to 1 less than its max and decrement cursor y by 1
fuck:
mov cl, 79
mov [ds:cursorX], cl
mov cl, [ds:cursorY]
dec cl
mov [ds:cursorY], cl
ret
vgaTextModeNewline:
;set x position to zero
mov bx, cursorX
mov cl, 0
mov [ds:bx], cl
;increment y position by 1
mov cl, [ds:cursorY]
inc cl
mov bx, cursorY
mov [ds:bx], cl
;call setCursorPosBasedOnData
;call calculateCursorValues
;check if cursor y position is equal to or greater than 23 and if so, scroll the screen by 2 lines
mov al, [ds:cursorY]
cmp al, 23
;if there are less than 23 rows of used text, there is no need to do any scrolling
jl vgaTextModeNewlineExit
;set cl for 2 rows of scrolling
mov cl, 2
call scrollScreen
;be sure to update the blinking cursor values and stuff
mov al, [ds:cursorY]
sub al, 2
mov [ds:cursorY], al
vgaTextModeNewlineExit:
;for things to show up correctly, recalculate cursor values whether or not the screen got moveda
call calculateCursorValues
ret
vgaTextModeBackspace:
push ax
mov al, [ds:capsState]
and al, 00100000b
cmp al, 0
pop ax
je textModeBackspaceNoInsert
jmp textModeBackspaceInsert
textModeBackspaceNoInsert:
call deleteAndScrollLeft
ret
textModeBackspaceInsert:
;first decrement cursorX
call decrementCursor
call calculateCursorValues
mov al, ' '
mov cl, 00001111b
call printChar
call decrementCursor
;call setCursorPosBasedOnData
call calculateCursorValues
ret
;call this subroutine any time you want to enter a new line in text mode
;screen scrolling is a driver-specific process so each video driver scrolling subroutine will have to contain code for scrolling on the target device
vgaNewline:
ret
;fetch the most recently typed-in thing from vram
vgaVramToCommandBuffer:
;calculate the correct line number from cursorY
mov al, [ds:cursorY]
mov ah, 0
mov bx, 00A0h
mul bx
mov cx, ax
;add the column number in cursorX to di so that the character prints to the correct column
mov al, 0
mov ah, 0
mov bx, 2
mul bx
add cx, ax
mov bx, cx
mov cx, commandHistory
vgaVramToCommandBufferCopyLoop:
mov al, [es:bx]
xchg bx, cx
mov [ds:bx], al
xchg bx, cx
inc cx
add bx, 2
cmp al, 0
jne vgaVramToCommandBufferCopyLoop
;done. now copy a null character just because
xchg bx, cx
;inc bx
mov al, 0
mov [ds:bx], al
;and then copy a $ character just for good measure. (the string print function was updated to terminate on null characters instead of $ but i dont want to change something that currently works)
inc bx
mov al, "$"
mov [ds:bx], al
ret