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
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_dispstring
;; @param string null terminated string to display
;; @return none
;; Print text onto the text screen
;;
jaspos_monitor_dispstring:
pop bp
pop ax
push bp
push di
push si
push es
push cx
push dx
mov si, ax
call jaspos_monitor_init
.loop:
lodsb ; Load a byte from the string into AL
cmp al, 0 ; Compare the byte with null
jz .quit ; Return if it's a null
cmp al, 1 ; Check to see if it's a colour control char
jz .setcolour ; If so, jump to handle it
push ax ; Push the ASCII code of the character to print
call jaspos_monitor_dispchar ; Print the character to the screen
mov di, [VGAMemPointer] ; Load DI with the new, updated VGA memory pointer
jmp .loop ; Loop
.setcolour:
lodsb ; Load the colour byte
mov [CharColour], al ; Set the CharColour to that byte
jmp .loop ; Go back to top of loop
.quit:
mov [VGAMemPointer], di ; Move the updated cursor position into VGAMemPointer
call jaspos_monitor_updatecursor ; Update the cursor position on screen
pop dx
pop cx
pop es
pop si
pop di
ret ; Return to where this function was called
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_dispchar
;; @param char ASCII code of char to show
;; @return none
;; Print single character to the screen
;;
jaspos_monitor_dispchar:
pop bp
pop ax
push bp
push es
push di
call jaspos_monitor_init ; Set up the registers ready for printing text
cmp di, 4000d ; Is DI (our VGA memory pointer) at the end of the screen?
jge .scroll ; If so, scroll the screen up a line
.checkchar:
cmp al, 8d ; Is the character a backspace?
jz .bs ; If so, jump to handle it
cmp al, 13d ; Is the byte a CR?
jz .cr ; if so, jump
cmp al, 10d ; Is the byte a LF?
jz .lf ; Jump if it is
stosb ; Store the byte in AL in memory. This happens if it's not a control char
mov al, [CharColour]
stosb
.quit:
mov [VGAMemPointer], di
pop di
pop es
ret
.bs:
sub di, 2
mov al, 32d
stosb
sub di, 2
mov al, [CharColour]
stosb
jmp .quit
.cr:
add di, 160d ; Add 160 to the byte pointer, moving it down one line
jmp .quit ; Jump back to top of the loop
.lf:
mov ax, di ; Move our current position/pointer into AX
xor dx, dx
mov di, 160d ; Load DI with 160 (# of bytes per line)
div di ; AX = AX / DI and DX = remainder
mul di ; AX = AX * DI
mov di, ax ; So now AX has been divided and had the remainder chopped off in doing so
xor ax, ax
jmp .quit ; and is now multiplied back, so the pointer is now at the start of current line
.scroll:
push ds
push ax
push di
push si
mov cx, 0xB800 ; Load DS with the video segment
mov ds, cx ;
mov si, 160d ;
xor di, di ;
mov cx, 3840d ;
rep movsb ; Move the bytes
xor al, al ; We'll be storing nulls to clear the last line
mov cx, 160d
mov di, 3840d
rep stosb
pop si
pop di
sub di, 160d
pop ax
pop ds
jmp .checkchar
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_init
;; @param none
;; @return none
;; Puts right values into ES and DI for putting
;; strings on the screen
;;
jaspos_monitor_init:
push ax
mov ax, 0xB800 ; Load AX with the VGA segment
mov es, ax ; and then ES
mov di, [VGAMemPointer] ; Load DI with VGA memory pointer
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_clear
;; @param none
;; @return none
;; Clears the text screen
;;
jaspos_monitor_clear:
push ax ; push our registers used
push cx
push di
push es
push 0x0000 ; Overly explicit XY co-ord
call jaspos_monitor_setcursorxy ; Set the cursor position
call jaspos_monitor_init
xor di, di ; Set our reading pointer to the base of the segment
mov cx, 2000d ; We'll be looping 2000 times
.loop:
mov al, 0x20 ; Load AL with character to clear address with
stosb ; Store our byte
mov al, [CharColour] ;
stosb ;
loop .loop ; Loop
xor ax, ax ; Zero-out AX
mov [VGAMemPointer], ax ; Load nulled-out AX into pointer
pop es
pop di
pop cx
pop ax ; pop registers we used back off stack
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_setcursorxy
;; @param coord word whose upper byte is the X lower byte is the Y coord
;; @return none
;; Set the XY position of the text cursor but NOT where the next
;; byte will be printed to the screen
;;
jaspos_monitor_setcursorxy:
pop bp
pop ax
push bp
push cx
mov cx, ax
xor ah, ah
mov bx, 160d
mul bx
shr cx, 8
shl cl, 1
add ax, cx
mov [VGAMemPointer], ax
pop cx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_getcursorxy
;; @param none
;; @return coord word whose upper byte is the X lower byte is the Y coord
;; Gets the XY position of the text cursor.
;;
jaspos_monitor_getcursorxy:
push dx
mov ax, [VGAMemPointer] ; Load the current cursor position
mov dx, 160d ; Divide it by 160 (bytes per row)
div dl ;
shr ah, 1 ; Divide the X by 2
pop dx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; name: jaspos_monitor_updatecursor
;; @param none
;; @return none
;; Moves where the current cursor's (the actual
;; flashing underscore) position is. Updates the
;; position according to the current VGA memory
;; pointer.
;;
jaspos_monitor_updatecursor:
push ax
push bx
push dx
call jaspos_monitor_getcursorxy
mov dh, al
mov dl, ah
mov ax, 0x0200 ; AH = 2 - set cursor pos.
xor bh, bh ; clear BH
int 0x10 ; Int 10.02 - set cursor position
pop dx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|