1 g_LineWidth=10
2 g_LineHeight=15
3 g_Speed=300;越小越快
4
5 g_DrawPosX=3
6 g_DisplayBuffer=0B80ah;
7 g_FrameColor=01110000b;框架颜色
8 g_PrepareColor=00100000b;准备方块颜色
9 g_CurrentColor=10111000b;当前方块颜色
10 g_ExistColor=01000000b;存在方块颜色
11
12 assume cs:code,ss:stack
13
14 stack segment
15 db 256 dup(0)
16 stack ends
17
18 ;每个格用两个并列字符
19 g_Current segment;当前下落的四个格
20 db 8 dup(0);x1,y1,x2,y2,x3,y3,x4,y4
21 db 8 dup(0);保存旋转初始值
22 g_Current ends
23
24 data segment;方块类型
25 db 0,0,1,0,2,0,3,0;I的初始格子
26 db 0,0,1,0,2,0,2,1;J
27 db 0,0,1,0,2,0,0,1;L
28 db 0,0,1,0,1,1,2,1;Z
29 db 1,0,2,0,0,1,1,1;S
30 db 0,0,1,0,0,1,1,1;O
31 db 0,0,1,0,2,0,1,1;T
32 data ends
33
34 g_State segment
35 db 'N';是否退出
36 db 2;下一个方块类型 0,1,2,3,4,5,6对应IJLZSOT
37 db 0;时间tick
38 dw 0,0
39 g_State ends
40
41 code segment
42 main:
43 call FNextRectToCurrent
44 call FGenNextRect
45 call FClear
46
47 mov ax,0;安装键盘回调函数
48 mov es,ax
49 mov ax,g_State
50 mov ds,ax
51 push es:[9*4]
52 pop ds:[3]
53 push es:[9*4+2]
54 pop ds:[5]
55 mov es:[9*4+2],cs
56 mov WORD ptr es:[9*4],offset FKeyboard
57
58 main_s:;游戏循环
59 mov ax,g_State
60 mov ds,ax
61 mov al,ds:[0]
62 cmp al,'Y'
63 je toexit
64 call GameLoop
65 jmp main_s
66 toexit:
67 mov ax,0
68 mov es,ax
69 mov ax,g_State
70 mov ds,ax
71 push ds:[5]
72 pop es:[9*4+2];还原键盘回调函数
73 push ds:[3]
74 pop es:[9*4]
75 mov ax,4c00H
76 int 21H
77
78 GameLoop:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79 call FSleep
80 call FRender
81 call FJugeDown
82 ret
83
84 FRender:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
85 call FClean
86 call FShowNextRect
87 call FShowFrame
88 call FShowCurrentRect
89 ret
90
91 FKeyboard:;键盘中断;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
92 push ax
93 push bx
94 push cx
95 push dx
96 push es
97 push ds
98 push si
99 push di
100 push bp
101
102 in al,60h
103 mov dl,al
104 pushf
105 pushf
106 pop bx
107 ;and bh,11111100b
108 push bx
109 popf
110
111 mov ax,g_State
112 mov ds,ax
113 call DWORD ptr ds:[3];调用原来的int 9
114 cmp dl,1;退出
115 je FKeyboard_exit
116 cmp dl,48h;上
117 je FKeyboard_change
118 cmp dl,50h;下
119 je FKeyboard_down
120 cmp dl,4bh;左
121 je FKeyboard_left
122 cmp dl,4dh;右
123 je FKeyboard_right
124 jmp FKeyboard_nop
125 FKeyboard_change:
126 call FDoChange
127 jmp FKeyboard_nop
128 FKeyboard_left:
129 call FDoLeft
130 jmp FKeyboard_nop
131 FKeyboard_right:
132 call FDoRight
133 jmp FKeyboard_nop
134 FKeyboard_down:
135 call FDoDown
136 jmp FKeyboard_nop
137 FKeyboard_exit:
138 mov ax,g_State
139 mov ds,ax
140 mov BYTE ptr ds:[0],'Y'
141
142 FKeyboard_nop:
143 pop bp
144 pop di
145 pop si
146 pop ds
147 pop es
148 pop dx
149 pop cx
150 pop bx
151 pop ax
152 iret
153
154 FDoLeft:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
155 mov ax,g_Current
156 mov ds,ax
157 mov cx,4
158 mov si,0
159 FDoLeft_s:
160 mov al,ds:[si+1];y
161 mov ah,ds:[si];x
162 cmp ah,0
163 jna FDoLeft_end
164 dec ah
165 push ds
166 push si
167 push cx
168 call FGetRect
169 pop cx
170 pop si
171 pop ds
172 cmp dl,g_ExistColor
173 je FDoLeft_end
174 add si,2
175 loop FDoLeft_s
176 mov cx,4
177 mov si,0
178 FDoLeft_s1:
179 mov ah,ds:[si];x
180 dec ah
181 mov ds:[si],ah
182 add si,2
183 loop FDoLeft_s1
184 call FRender
185 FDoLeft_end:
186 ret
187
188 FDoRight:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
189 mov ax,g_Current
190 mov ds,ax
191 mov cx,4
192 mov si,0
193 FDoRight_s:
194 mov al,ds:[si+1];y
195 mov ah,ds:[si];x
196 cmp ah,g_LineWidth-1
197 jnb FDoRight_end
198 inc ah
199 push ds
200 push si
201 push cx
202 call FGetRect
203 pop cx
204 pop si
205 pop ds
206 cmp dl,g_ExistColor
207 je FDoRight_end
208 add si,2
209 loop FDoRight_s
210 mov cx,4
211 mov si,0
212 FDoRight_s1:
213 mov ah,ds:[si];x
214 inc ah
215 mov ds:[si],ah
216 add si,2
217 loop FDoRight_s1
218 call FRender
219 FDoRight_end:
220 ret
221
222 FApplyChange:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
223 mov ax,g_Current
224 mov ds,ax
225 mov cx,8
226 mov di,0
227 FApplyChange_loop:
228 mov al,ds:[di+8]
229 mov ds:[di],al
230 inc di
231 loop FApplyChange_loop
232 ret
233
234
235
236 FDoChange:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
237 mov ax,g_Current
238 mov ds,ax
239
240 mov bl,g_LineWidth;偏移值x
241 mov bh,g_LineHeight;y
242 mov cx,4
243 mov di,0
244 FDoChange_getxy:
245 mov al,ds:[di];
246 cmp al,bl
247 jnb FDoChange_getxy_xend
248 mov bl,al
249 FDoChange_getxy_xend:
250 mov al,ds:[di+1]
251 cmp al,bh
252 jnb FDoChange_getxy_yend
253 mov bh,al
254 FDoChange_getxy_yend:
255 add di,2
256 loop FDoChange_getxy
257
258 mov dl,0;y偏移
259 mov cx,4
260 mov di,0
261 FDoChange_loop:;(x,y)-->(-y,x)
262 mov al,ds:[di];(x,)-->(,x)
263 sub al,bl
264 mov ds:[di+9],al
265
266 mov al,ds:[di+1];(,y)-->(-y,)
267 sub al,bh
268 cmp al,dl
269 jna FDoChange_off
270 mov dl,al;y最大偏移
271 FDoChange_off:
272 mov ah,0
273 sub ah,al;-y
274 mov ds:[di+8],ah
275 add di,2
276 loop FDoChange_loop
277
278 mov di,8
279 mov cx,4
280 FDoChange_s:
281 add ds:[di],dl
282 add di,2
283 loop FDoChange_s
284
285 call FApplyChange
286 call FRender
287 ret
288
289 FDoDown:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
290 call FJugeDown
291 call FRender
292 ret
293
294 FSleep:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
295 mov bx,g_Speed
296 FSleep0:
297 mov ah, 2ch
298 int 21h
299 mov ax,g_State
300 mov es,ax
301 mov es:[2], dl
302 FSleep1:
303 mov ah, 2ch
304 int 21h
305 mov ax,g_State
306 mov es,ax
307 cmp es:[2], dl
308 je FSleep1
309
310 sub bx, 55
311 cmp bx, 0
312 jg FSleep0
313 ret
314
315 FKill:
316 mov cx,g_LineHeight;检查的行
317 mov bx,0;删除了多少行
318 FKill_loop:
319 mov al,cl;检查的行
320 dec al
321 push cx
322 push bx
323 call FJugeKill_line;检查
324 pop bx
325 pop cx
326 cmp dl,'Y'
327 jne FKill_notkill
328 je FKill_kill
329
330 FKill_kill:;清除
331 push bx
332 push cx
333 mov bl,cl
334 dec bl
335 mov al,bl
336 call FCopyLine;清除当前行
337 pop cx
338 pop bx
339 inc bx
340 jmp FKill_next
341 FKill_notkill:;不清除
342 cmp bx,0
343 je FKill_next
344 push bx
345 push cx
346 mov al,cl
347 dec al;from
348 add bl,al;to
349 call FCopyLine
350 pop cx
351 pop bx
352 FKill_next:;下一行
353 loop FKill_loop
354 ret
355
356 FCopyLine:;某行剪切到某行,同一行时清除。输入from al,to bl;;;;;;;;;;;;;;;;;;;;;;
357 mov cx,g_LineWidth
358 FCopyLine_loop:
359 mov ah,cl
360 dec ah;x
361
362 push cx
363 push ax
364 push bx
365 call FGetRect
366 pop bx
367 pop ax
368 pop cx
369
370 push cx
371 push ax
372 push bx
373 push dx
374 mov dl,0
375 call FShowRect
376 pop dx
377 pop bx
378 pop ax
379 pop cx
380
381 push ax
382 push cx
383 push bx
384 mov al,bl;new y
385 call FShowRect
386 pop bx
387 pop cx
388 pop ax
389
390 loop FCopyLine_loop
391 ret
392
393 FJugeKill_line:;是否可以清除某行,输入al:y,输出dl,是否可清除
394 mov cx,g_LineWidth
395 mov ah,0;x
396 FJugeKill_line_s:
397 push cx
398 push ax
399 call FGetRect
400 pop ax
401 pop cx
402 cmp dl,g_ExistColor
403 jne FJugeKill_line_n
404 inc ah
405 loop FJugeKill_line_s
406 mov dl,'Y'
407 jmp FJugeKill_line_y
408 FJugeKill_line_n:
409 mov dl,'N'
410 FJugeKill_line_y:
411 ret
412
413 FJugeDown:;是否可以下降处理;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
414 mov ax,g_Current
415 mov ds,ax
416 mov di,0
417 mov cx,4
418 FJugeDown_s:
419 mov al,ds:[di+1];y
420 cmp al,g_LineHeight-1
421 jnb FJugeDown_false;y>=高度
422 inc al
423 mov ah,ds:[di];x
424 push di
425 push cx
426 push ds
427 call FGetRect
428 pop ds
429 pop cx
430 pop di
431 cmp dl,g_ExistColor
432 je FJugeDown_false
433 add di,2
434 loop FJugeDown_s
435
436 FJugeDown_true:;可下降
437 mov di,0
438 mov cx,4
439 FJugeDown_s1:
440 mov al,ds:[di+1];y
441 inc al
442 mov ds:[di+1],al
443 add di,2
444 loop FJugeDown_s1
445 jmp FJugeDown_end
446
447 FJugeDown_false:;不可下降
448 mov di,0
449 mov cx,4
450 FJugeDown_s2:
451 mov al,ds:[di+1];y
452 mov ah,ds:[di];x
453 mov dl,g_ExistColor
454 push di
455 push ds
456 push cx
457 call FShowRect
458 pop cx
459 pop ds
460 pop di
461 add di,2
462 loop FJugeDown_s2
463 call FKill;
464
465 call FNextRectToCurrent
466 call FGenNextRect
467 call FJugeFail
468
469 FJugeDown_end:
470 ret
471
472 FJugeFail:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
473 mov ax,g_Current
474 mov ds,ax
475 mov di,0
476 mov cx,4
477 FJugeFail_s:
478 mov al,ds:[di+1];y
479 mov ah,ds:[di];x
480 push cx
481 push di
482 call FGetRect
483 pop di
484 pop cx
485 cmp dl,g_ExistColor
486 je FJugeFail_fail
487 add di,2
488 loop FJugeFail_s
489 jmp FJugeFail_nop
490 FJugeFail_fail:
491 mov ax,g_State
492 mov ds,ax
493 mov BYTE ptr ds:[0],'Y'
494 FJugeFail_nop:
495 ret
496
497 FClear:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
498 mov ax,g_DisplayBuffer
499 mov ds,ax
500 mov cx,20
501 mov bx,0
502 FClear_s:
503 push cx
504 mov cx,80
505 FClear_s1:
506 mov BYTE ptr ds:[bx],' '
507 mov BYTE ptr ds:[bx+1],0
508 add bx,2
509 loop FClear_s1
510 pop cx
511 loop FClear_s
512 ret
513
514 FClean:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
515 mov ax,g_DisplayBuffer
516 mov ds,ax
517 mov cx,80*g_LineHeight
518 mov bx,0
519 FClean_s:
520 mov dl,ds:[bx+1]
521 cmp dl,g_FrameColor
522 je FClean_nop
523 cmp dl,g_ExistColor
524 je FClean_nop
525 mov BYTE ptr ds:[bx+1],0
526
527 FClean_nop:nop
528 add bx,2
529 loop FClean_s
530 ret
531
532 FShowCurrentRect:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
533 mov ax,g_Current
534 mov ds,ax
535 mov di,0
536 mov cx,4
537 mov dl,g_CurrentColor
538 FShowCurrentRect_s:
539 mov ah,ds:[di]
540 mov al,ds:[di+1]
541
542 push ds
543 push di
544 push cx
545 push dx
546 call FShowRect
547 pop dx
548 pop cx
549 pop di
550 pop ds
551
552 add di,2
553 loop FShowCurrentRect_s
554 ret
555
556 FGenNextRect:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
557 mov ah,2ch
558 mov al,0
559 int 21h;CH=小时,CL=分钟,DH=秒,DL=百分秒
560 mov ah,0
561 mov al,dl
562 mov dl,7
563 div dl
564 mov bl,ah;余数作为随机值
565 mov ax,g_State
566 mov ds,ax
567 mov BYTE ptr ds:[1],bl
568 ret
569
570 FNextRectToCurrent:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
571 mov ax,g_State
572 mov ds,ax
573 mov al,ds:[1]
574 mov ah,8
575 mul ah
576 mov bx,ax;位移
577 mov ax,g_Current
578 mov ds,ax
579 mov ax,data
580 mov es,ax
581 mov cx,8
582 mov di,0
583 FNextRectToCurrent_s:
584 mov al,es:[bx+di]
585 mov ds:[di],al
586 inc di
587 loop FNextRectToCurrent_s
588 ret
589
590 FShowNextRect:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
591 mov ax,g_State
592 mov es,ax
593 mov al,es:[1];方块类型
594 mov ah,8
595 mul ah
596 mov si,ax;方块类型在data位置
597 mov ax,data
598 mov es,ax
599
600 mov cx,4
601 mov dl,g_PrepareColor
602 FShowNextRect_s:
603 mov al,es:[si+1];y
604 mov ah,es:[si];x
605 add ah,g_LineWidth+2
606
607 push cx
608 push ax
609 push si
610 push es
611 push dx
612 call FShowRect
613 pop dx
614 pop es
615 pop si
616 pop ax
617 pop cx
618
619 add si,2
620 loop FShowNextRect_s
621 ret
622
623 FShowRect:;画一个格 输入格:ah:x,al:y,dl颜色;;;;;;;;;;;;;;;;;;;;;
624 mov bh,ah
625 mov bl,160
626 mul bl
627 mov si,ax
628 mov al,4
629 mul bh
630 add si,ax;
631 mov ax,g_DisplayBuffer
632 mov ds,ax
633 mov BYTE ptr ds:[si+g_DrawPosX*2+2],' '
634 mov ds:[si+g_DrawPosX*2+3],dl
635 mov BYTE ptr ds:[si+g_DrawPosX*2+4],' '
636 mov ds:[si+g_DrawPosX*2+5],dl
637 ret
638
639 FGetRect:;输入格:ah:x,al:y 输出dl颜色
640 mov bh,ah
641 mov bl,160
642 mul bl
643 mov si,ax
644 mov al,4
645 mul bh
646 add si,ax;
647 mov ax,g_DisplayBuffer
648 mov ds,ax
649 mov dl,ds:[si+g_DrawPosX*2+3]
650 ret
651
652 FShowFrame:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
653 mov ax,g_DisplayBuffer
654 mov ds,ax
655 mov cx,g_LineHeight
656 mov bx,0
657 mov si,g_DrawPosX
658 add si,g_DrawPosX
659 FShowFrame_s:
660 mov BYTE ptr ds:[bx+g_DrawPosX*2],' '
661 mov BYTE ptr ds:[bx+g_DrawPosX*2+1],g_FrameColor
662 mov BYTE ptr ds:[bx+g_DrawPosX*2+g_LineWidth*4+2],' '
663 mov BYTE ptr ds:[bx+g_DrawPosX*2+g_LineWidth*4+3],g_FrameColor
664 add bx,160
665 loop FShowFrame_s
666 mov cx,g_LineWidth*2+2
667 mov si,0
668 FShowFrame_s1:
669 mov BYTE ptr ds:[bx+si+g_DrawPosX*2],' '
670 mov BYTE ptr ds:[bx+si+g_DrawPosX*2+1],g_FrameColor
671 add si,2
672 loop FShowFrame_s1
673 ret
674 code ends
675 end main