-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbreakout.asm
253 lines (191 loc) · 3.25 KB
/
breakout.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
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
244
245
246
247
248
249
250
251
252
253
org 0x7C00
bits 16
cpu 8086
SCREEN_WIDTH equ 80
SCREEN_HEIGHT equ 25
PADDLE_COLOR equ 0b11101110
PADDLE_COUNT equ 8
PADDLE_ROWS equ 6
start:
; Init routine
xor ax, ax
mov ss, ax
mov ds, ax
; Insure correct video mode
inc ax
inc ax
int 0x10
mov ax, 0xB800
mov es, ax ; Video memory
; Stack
mov sp, 0x7C00
; Clearing variable memory
mov di, END_VARIABLES-START_VARIABLES-1
.clear:
mov byte [START_VARIABLES+di], 1
dec di
jns .clear
mov byte [BALL_X], SCREEN_WIDTH / 2
mov byte [BALL_Y], SCREEN_HEIGHT / 3 * 2
mov byte [PADDLE_X], SCREEN_WIDTH / 2 - 4
mov byte [BALL_XV], -1
mov byte [BALL_YV], 1
mainloop:
.delay:
; Wait frames
xor ah, ah
int 0x1A
cmp dx, [OLD_TIME] ; 18.2 clock ticks per second
je .delay
mov [OLD_TIME], dx
; Clear screen
xor ax, ax
xor di, di
mov cx, SCREEN_WIDTH * SCREEN_HEIGHT * 2
rep stosb
; Draw paddles
mov di, PADDLE_COUNT * PADDLE_ROWS - 1
.drawPaddles:
; MISC: Inc color by di to add color
; If the thing is 1, set color
mov ax, PADDLE_COLOR
add ax, di
mov bl, [PADDLES + di]
mul bl
push di
; Use mul to calculate coridnates
push ax
mov ax, 20
mul di
mov di, ax
pop ax
mov cx, 160 / 8
rep stosb
pop di
dec di
jns .drawPaddles
.drawPaddle:
xor dx, dx
mov dl, [PADDLE_X]; Insure 16 bit
mov di, dx
mov ax, 2
mul di
mov di, ax
mov ax, PADDLE_COLOR
add di, SCREEN_WIDTH * 2 * 20
mov cx, 160 / 8
rep stosb
.input:
mov ah, 0x02
int 0x16
mov bl, [PADDLE_X]
test al, 0x08
jne .right
test al, 0x04
je .endKeys
.left:
cmp bl, 0
je .endKeys
sub bl, 1
jmp .endKeys
.right:
cmp bl, SCREEN_WIDTH - 10
je .endKeys
add bl, 1
.endKeys:
mov byte [PADDLE_X], bl
call ball
jmp mainloop
ball:
; Now update ball
mov al, [BALL_X]
cmp al, 0
jne .left
mov byte [BALL_XV], 1
.left:
cmp al, SCREEN_WIDTH
jne .endx
mov byte [BALL_XV], -1
.endx:
; Now Y axis
mov al, [BALL_Y]
cmp al, 0
jne .bottom
mov byte [BALL_YV], -1
.bottom:
cmp al, SCREEN_HEIGHT
; Player dead, restart
je start
; Paddle collision
cmp al, 19
jne .endPaddleCollision
mov al, [BALL_X]
mov bl, [PADDLE_X]
cmp al, bl
jle .endPaddleCollision
add bl, 160 / 8 / 2
cmp al, bl
jg .endPaddleCollision
mov byte [BALL_YV], 1
.endPaddleCollision:
; Now to break blockes
; Not in collision range
; Al is position
xor ax, ax
mov al, PADDLE_COUNT
mov bl, [BALL_Y]
dec bl
cmp bl, PADDLE_ROWS
jge .endBlockBraking
mul bl
push ax
; Calculate block number
xor ax, ax
mov al, [BALL_X]
mov bl, 10
div bl
xor ah, ah
mov bl, al
mov di, ax
pop ax
add di, ax
; If broken do nothing
mov cl, [PADDLES + di]
cmp cl, 0
je .endBlockBraking
mov byte [BALL_YV], -1
mov byte [PADDLES + di], 0
.endBlockBraking:
xor ax, ax
mov al, [BALL_Y]
sub al, [BALL_YV]
mov [BALL_Y], al
mov dl, SCREEN_WIDTH * 2
mul dl
push ax
xor ax, ax
; Fetch X at the same time increase speed
mov al, [BALL_X]
add al, [BALL_XV]
mov [BALL_X], al
mov di, 2
mul di
pop di
add di, ax
inc di
mov byte [es:di], PADDLE_COLOR
ret
OLD_TIME: equ 16
; Boot stuff
times 510 - ($-$$) db 0
dw 0xaa55
; Place where I store my vars
[absolute 0x7E00]
START_VARIABLES:
PADDLE_X resb 1
PADDLES resb PADDLE_COUNT * PADDLE_ROWS
BALL_X resb 1
BALL_Y resb 1
BALL_XV resb 1
BALL_YV resb 1
END_VARIABLES: