aboutsummaryrefslogtreecommitdiff
path: root/textvga.asm
blob: 19f42e5a143b89031901a9ecc00e856bfc502c5a (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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;