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
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Print text onto the text screen
OutText:
pop ax
pop si
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
.loop:
lodsb ; Load a byte from the string into AL
or al, al ; Do a byte comarison on the char
jz .Quit ; Exit the function 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
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 memory. This happens if it's not a control char
mov al, [CharColour] ; Load the current char colour
stosb ; Store the char colour in the byte after the character
jmp short .loop ; Loop
.cr:
add di, 160d ; Add 160 to the byte pointer, thus moving the pointer down one line
jmp short .loop ; Jump back to top of the loop
.lf:
mov ax, di ; Move our current position/pointer into AX
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
jmp short .loop ; and is now multiplied back, so the pointer is now at the start of current line
.SetColour:
lodsb ; Load the byte
mov [CharColour], al ; Set the CharColour to that byte
jmp short .loop ; Go back to top of loop
.Quit:
mov [VGAMemPointer], di ; Move the updated cursor position into VGAMemPointer
ret ; Return to where this function was called
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Clear the text screen
ClearScreen:
push ax ; push our registers used
push cx
push di
push es
mov ax, 0xB800 ; Load AX with the VGA segment
mov es, ax ; And then load ES with AX
xor di, di ; Set our reading pointer to the base of the segment
mov cx, 0x7D0 ; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set the cursor position
SetCursorPosition:
push ax ; Push our registers
push bx ;
mov ah, 2 ; Subfunction 2 - set cursor pos.
xor bh, bh ; clear BH
int 0x10 ; Int 10.02 - set cursor position
pop bx ; Pop registers back off stack
pop ax ;
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Convert decimal in dx to string in NumberBuffer
NumberToString:
std
pop dx
mov cx, 0x5
lea di, [NumberBuffer + 4]
.loop:
mov ax, dx
mov dx, 10d
div dl
mov dl, al
mov al, ah
add al, 0x30
stosb
loop .loop
cld
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Convert he value in al to string in HexNumberBuffer
HexToString:
mov di, HexNumberBuffer
xor ah, ah ; zero-out ah so shifiting doesn't cause bits of ah to come into al
push ax ; save AL
shr al, 4 ; Shift AL along 4 bits
add al, 48d ; add 48 onto it
cmp al, 57d ; see if it's > 9
jg .letter
.return:
stosb
pop ax
shl al, 4
shr al, 4
add al, 48d
cmp al, 57d
jg .letter_last_digit
stosb
.quit:
ret
.letter:
add ax, 7d
jmp .return
.letter_last_digit:
add ax, 7d
stosb
jmp .quit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|