-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintro.asm
196 lines (154 loc) · 4.5 KB
/
intro.asm
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
; ***************************************************************************************
; ***************************************************************************************
; ** Simple into function (display basic messages)
; ** Require setup.asm
.DATA
memory_size db 5 dup(0)
dos_major db 2 dup (0)
dos_minor db 2 dup (0)
msg_welcome db "Bienvenue Joueur " ;, (49 + PLAYER_NUMBER), 13, 10, "$"
msg_welcome_player db 49 ; add PLAYER_NUMBER
db 13, 10, "$"
msg_memsize db "Vous avez $"
msg_memsize2 db "ko de memoire disponible", 13, 10, "$"
msg_dosver db "Vous utilisez DOS $"
msg_dosver2 db 13, 10, "$"
msg_explanation db 13, 10, "Controles:", 13, 10
db "Fleches haut/bas/droite/gauche ==> direction", 13, 10
db "Espace ==> change couleur", 13, 10
db "R ==> recommence", 13, 10
db "Echap. ==> quitter le jeu", 13, 10, "$"
.CODE
INTRO:
; simple welcome piece of code
; Frankly not very well written but that's not critical
mov al, [PLAYER_NUMBER]
add al, 49
mov [msg_welcome_player], al
mov dx, offset msg_welcome
mov ah, 9
int 21h
; call int 12h to check how much memory we've got
; ax will contain the memory size
; int 12h
; int 12h is not super accurate (it just gives the max amount of potentially free memory)
; Better solution is to use 48h / int 21h and request the max - which is bound to fail with DOSBOX
; bx will return the largest amount of 16bytes pages that can be requested
mov bx, 0ffffh
mov ah, 48h
int 21h
mov ax, bx
shr ax, 6
; convert it to ASCII
mov di, offset memory_size
call convert_ax_ascii
; Then print it out
mov dx, offset msg_memsize
mov ah, 9
int 21h
mov si, offset memory_size
mov cx, 5
call print_ascii
mov dx, offset msg_memsize2
mov ah, 9
int 21h
; Now check dos version
mov ax, 3000h
int 21h
; Convert the major/minor versions to ASCII
mov di, offset dos_major
call convert_al_ascii
mov al, ah
mov di, offset dos_minor
call convert_al_ascii
; and print it
mov dx, offset msg_dosver
mov ah, 9
int 21h
mov si, offset dos_major
mov cx, 2
call print_ascii
mov dl, 2eh
mov ah, 02h
int 21h
mov si, offset dos_minor
mov cx, 2
call print_ascii
mov dx, offset msg_dosver2
mov ah, 9
int 21h
; Now explain the controls
mov dx, offset msg_explanation
mov ah, 9
int 21h
ret
; ********************************************************************************************
; ********************************************************************************************
; ** Various functions
; Very simple algo to convert a 16bit number in AX into an ASCII equivalent
convert_ax_ascii:
; AX = number to convert
; DI = address to store the output (assume ds for segment)
; Note that the data is stored backwards (i.e. "640" will be stored "046")
push ax
push bx
push dx
push di
mov bx, 10
; The algo is about dividing by 10 the output
; and convert the remainder to ASCII
@@decimal_conv:
xor dx, dx
div bx
add dl, 30h
mov [di], dl
inc di
or ax, ax
jnz @@decimal_conv
pop di
pop dx
pop bx
pop ax
ret
; Similar function but for AL (8bits) - a lot easier
convert_al_ascii:
; AL = number to convert
; DI = address to store the output (assume ds for segment)
; Note that the data is stored backwards (i.e. "64" will be stored "46")
push ax
push di
@@decimal_al_conv:
aam
add al, 30h
mov [di], al
inc di
mov al, ah
or al, al
jnz @@decimal_al_conv
pop di
pop ax
ret
print_ascii:
; CX = size of string
; SI = address of the string to print out (assume characters are stored in reverse)
push si
push cx
push ax
push dx
add si, cx
dec si
mov ah, 02h
@@print_check:
mov dl, [si]
or dl, dl
jz @@noprint ; do not print if you find 0
int 21h
@@noprint:
dec si
dec cx
jnz @@print_check
pop dx
pop ax
pop cx
pop si
ret