汇编写俄罗斯方块

assume cs:code,ds:data,ss:stack

data segment

SCREEN_COLOR		dw	0700H
SCREEN_LOCTION		dw	160*3

SCREEN_ROW		dw	19
SCREEN_COL		dw	16


NEXT_ROW		dw	160

					;0123456789ABCDEF
SCREEN			db	18 dup ('1000000000000001')
			db		'1111111111111111'


BLOCK_O			db	'1100'
			db	'1100'
			db	'0000'
			db	'0000'

BLOCK_I			db	'0000'
			db	'1111'
			db	'0000'
			db	'0000'

			db	'0100'
			db	'0100'
			db	'0100'
			db	'0100'

BLOCK_S			db	'0000'
			db	'0110'
			db	'1100'
			db	'0000'

			db	'0100'
			db	'0110'
			db	'0010'
			db	'0000'

BLOCK_Z			db	'0000'
			db	'1100'
			db	'0110'
			db	'0000'

			db	'0010'
			db	'0110'
			db	'0100'
			db	'0000'

BLOCK_T			db	'0100'
			db	'1110'
			db	'0000'
			db	'0000'

			db	'0100'
			db	'0110'
			db	'0100'
			db	'0000'

			db	'0000'
			db	'1110'
			db	'0100'
			db	'0000'

			db	'0100'
			db	'1100'
			db	'0100'
			db	'0000'

BLOCK_J			db	'0010'
			db	'0010'
			db	'0110'
			db	'0000'

			db	'0000'
			db	'1000'
			db	'1110'
			db	'0000'

			db	'0110'
			db	'0100'
			db	'0100'
			db	'0000'

			db	'0000'
			db	'1110'
			db	'0010'
			db	'0000'

BLOCK_L			db	'0100'
			db	'0100'
			db	'0110'
			db	'0000'

			db	'0000'
			db	'1110'
			db	'1000'
			db	'0000'

			db	'0110'
			db	'0010'
			db	'0010'
			db	'0000'

			db	'0000'
			db	'0010'
			db	'1110'
			db	'0000'


BLOCK			dw	OFFSET BLOCK_O
			dw	OFFSET BLOCK_I
			dw	OFFSET BLOCK_S
			dw	OFFSET BLOCK_Z
			dw	OFFSET BLOCK_T
			dw	OFFSET BLOCK_J
			dw	OFFSET BLOCK_L

BLOCK_MAX_ROW		dw	2,4,3,3,3,3,3
BLOCK_MAX_COL		dw	2,4,3,3,3,3,3

BLOCK_ROW		dw	4
BLOCk_COL		dw	4

BLOCK_COLOR		dw	2201H

LEFT			db	4BH
RIGHT			db	4DH
DOWN			db	50H
BLANK			db	39H

BACK_GROUND_COLOR	dw	0030H

isAllowMoveDown		dw	1

BUTTON_BLOCK_COLOR	dw	4432H

BLOCK_HIGH		dw	4000

BLOCK_MAX_STATUS	dw	0,1,1,1,3,3,3
BLOCK_STATUS		dw	0
BLOCK_NOW_STATUS	dw	0
BLOCK_ORG_STATUS	dw	0	


string			db	'GAME OVER',0

data ends


stack segment stack
	db	128 dup (0)
stack ends


code segment
	
	start:	mov ax,stack
		mov ss,ax
		mov sp,128
	

		;call clear_07E00H
		call sav_old_int9
		call set_new_int9
		call cpy_Tetris


		mov bx,0
		push bx
		mov bx,9000H
		push bx
		retf


		mov ax,4C00H
		int 21H


;============================================================
Tetris:		call init_reg
		call clear_screen
		call init_screen
		call init_block_high

		
nextBlock:	cli
		call init_block_type
		call init_block_loction
		call check_game_over
		call print_block
		sti

nextDelay:	call delay
		cli
		call isMoveDown
		cmp isAllowMoveDown,1
		je isNextDelay
		sti
		jmp nextBlock

isNextDelay:	sti
		jmp nextDelay



		;call is_turn_block

testA:		mov ax,1000H
		jmp testA


		mov ax,4C00H
		int 21H



;==============================================================
check_game_over:
		push bx
		push si

		mov cx,BLOCK_ROW

checkGameOver:	push cx
		push bx
		mov cx,BLOCK_COL

gOver:		cmp byte ptr ds:[si],'1'
		jne nextCol_gOver
		cmp byte ptr es:[bx],'0'
		jne GameOver
nextCol_gOver:	add bx,2
		inc si
		loop gOver

		pop bx
		pop cx
		add bx,NEXT_ROW
		loop checkGameOver

		pop si
		pop bx
		ret

;==============================================================
GameOver:	add sp,6

		call clear_screen
		mov si,OFFSET string
		mov di,160*10 + 35*2
		call show_string
		mov ax,4C00H
		int 21H


;==============================================================
show_string:	push dx
		push si
		push ds
		
showString:	mov dl,ds:[si]
		cmp dl,0
		je getStringRet
		mov es:[di],dl
		inc si
		add di,2
		jmp showString


getStringRet:	pop ds
		pop si
		pop dx
		ret
;==============================================================
delay:		push ax
		push dx


		mov dx,8000H
		mov ax,0


delaying:	sub ax,1000H
		sbb dx,0
		cmp dx,0
		jne delaying

		pop dx
		pop ax
		ret
;==============================================================
init_block_high:
		mov BLOCK_HIGH,4000
		ret
;==============================================================
print_block:	push bx
		push si

		mov cx,BLOCK_ROW
		mov dx,BLOCK_COLOR

printBlock:	push cx
		push bx
		push si
		mov cx,BLOCK_COL

printRow:	cmp byte ptr ds:[si],'1'
		jne printCol
		mov es:[bx],dx
printCol:	add bx,2
		inc si
		loop printRow

		pop si
		pop bx
		pop cx
		add si,4
		add bx,NEXT_ROW
		loop printBlock


		pop si
		pop bx
		ret
;==============================================================
init_block_loction:
		mov bx,SCREEN_LOCTION
		add bx,7*2
		ret
;==============================================================
init_block_type:	
		;mov bx,0
		;mov bx,2
		call get_block_type
		mov si,ds:BLOCK[bx]

		push ds:BLOCK_MAX_ROW[bx]
		pop BLOCK_ROW

		push ds:BLOCK_MAX_COL[bx]
		pop BLOCK_COL

		mov isAllowMoveDown,1


		push ds:BLOCK_MAX_STATUS[bx]
		pop BLOCK_STATUS

		mov BLOCK_ORG_STATUS,si
		
		mov BLOCK_NOW_STATUS,0

		ret

;==============================================================
get_block_type:	push ax
		push dx

		mov dx,0

		mov al,0
		out 70H,al
		in al,71H

		mov dl,al

		shr al,1
		shr al,1
		shr al,1
		shr al,1

		mov bl,10

		mul bl

		add ax,dx

		mov dx,0
		
		mov bx,7
		div bx

		mov bx,dx
		add bx,bx


		pop dx
		pop ax
		ret
;==============================================================
init_screen:	mov bx,SCREEN_LOCTION
		mov si,OFFSET SCREEN

		mov cx,SCREEN_ROW
		
initScreen:	push cx
		push bx
		mov cx,SCREEN_COL

initCol:	mov dx,0
		mov dl,ds:[si]
		cmp dl,'1'
		jne initRow
		or dh,00010001B
initRow:	mov es:[bx],dx
		add bx,2
		inc si
		loop initCol

		pop bx
		pop cx
		add bx,NEXT_ROW
		loop initScreen

		ret
;==============================================================
clear_screen:	mov bx,0
		mov dx,SCREEN_COLOR
		mov cx,2000

clearScreen:	mov es:[bx],dx
		add bx,2
		loop clearScreen

		ret
;==============================================================
init_reg:
		mov bx,0B800H
		mov es,bx

		mov bx,data
		mov ds,bx
		ret
;==============================================================
new_int9:	push ax

		in al,60H
		pushf 
		call dword ptr cs:[200H]

		cmp al,LEFT
		je isLeft
		cmp al,RIGHT
		je isRight
		cmp al,DOWN
		je isDown
		cmp al,BLANK
		je isBlank
	
		cmp al,3BH
		jne int9Ret
		call change_screen_color


int9Ret:	pop ax
		iret


;=============================================================
isLeft:		mov di,160*3 + 40*2
		mov byte ptr es:[di],'L'
		call isMoveLeft
		jmp int9Ret

isRight:	mov di,160*3 + 40*2
		mov byte ptr es:[di],'R'
		call isMoveRight
		jmp int9Ret

;*****************************************************************
isDown:		mov di,160*3 + 40*2
		mov byte ptr es:[di],'D'
		call isMoveDown
		cmp isAllowMoveDown,0
		je isNextBlock
		jmp int9Ret

isNextBlock:	pop ax
		add sp,4
		popf
		jmp nextBlock
;*******************************************************************

isBlank:	mov di,160*3 + 40*2
		mov byte ptr es:[di],'B'
		call is_turn_block
		jmp int9Ret



;=============================================================
is_turn_block:	push bx
		push si
		push BLOCK_NOW_STATUS

		inc BLOCK_NOW_STATUS
		mov dx,BLOCK_NOW_STATUS
		cmp dx,BLOCK_STATUS
		jna checkTurnOne
		mov si,BLOCK_ORG_STATUS
		mov BLOCK_NOW_STATUS,0
		jmp checkTurnTwo
checkTurnOne:	add si,16
checkTurnTwo:	push si


		mov cx,BLOCK_ROW

isTurnBlock:	push cx
		push bx
		push si
		mov cx,BLOCK_COL

tBlock:		cmp byte ptr ds:[si],'1'
		jne nextCol_tBlock
		cmp byte ptr es:[bx],1
		je nextCol_tBlock
		cmp byte ptr es:[bx],'0'
		jne noTurnBlock
nextCol_tBlock:	add bx,2
		inc si
		loop tBlock



		pop si
		pop bx
		pop cx
		add si,4
		add bx,NEXT_ROW
		loop isTurnBlock		

		pop si
		add sp,4
		pop bx
		call clear_old_block
		call print_block
		ret
		




noTurnBlock:	add sp,8
		;mov di,bx
		;mov word ptr es:[di],5535H
		pop BLOCK_NOW_STATUS
		pop si
		pop bx
;		mov di,160*4 + 40*2
;		mov byte ptr es:[di],'X'
		ret
;=============================================================
isMoveDown:	push bx

		mov cx,BLOCK_ROW
		
moveDown:	push cx
		push bx
		mov cx,BLOCK_COL

mDown:		cmp byte ptr es:[bx],1
		jne nextCol_mDown
		cmp byte ptr es:[bx+160],1
		je nextCol_mDown
		cmp byte ptr es:[bx+160],'0'
		jne noMoveDown		
nextCol_mDown:	add bx,2
		loop mDown

		pop bx
		pop cx
		add bx,NEXT_ROW
		loop moveDown

		pop bx
		call clear_old_block
		add bx,NEXT_ROW
		call print_block
		ret


noMoveDown:	add sp,4
		pop bx
		
		mov isAllowMoveDown,0
		call set_button_block_color
		call get_row
		call is_clear_row
		ret



;=============================================================
is_clear_row:	push bx


		mov cx,BLOCK_ROW


isClearRow:	push cx
		push bx
		mov cx,14
		mov dx,bx

checkRow:	cmp byte ptr es:[bx],'2'
		jne nextRow_cRow
		add bx,2
		loop checkRow

		mov bx,dx
		call clear_row

		cmp bx,BLOCK_HIGH
		je isNextRow_cRow	
		call reDraw_screen

nextRow_cRow:	pop bx
		pop cx
		add bx,NEXT_ROW
		loop isClearRow
		

		pop bx
		ret


isNextRow_cRow:	add BLOCK_HIGH,160
		jmp nextRow_cRow


;=============================================================
reDraw_screen:	push bx
		push dx


		mov ax,dx
		sub ax,BLOCK_HIGH
		mov dx,0

		mov bx,NEXT_ROW
		
		div bx

		mov cx,ax

		pop dx

		mov di,dx
		mov si,dx
		sub si,NEXT_ROW

drawRow:	push cx
		push si
		push di
		mov cx,14

drawCol:	push es:[si]
		pop es:[di]
		add si,2
		add di,2
		loop drawCol

		pop di
		pop si
		pop cx
		sub si,NEXT_ROW
		sub di,NEXT_ROW
		loop drawRow


		pop bx
		mov bx,BLOCK_HIGH
		call clear_row

		add BLOCK_HIGH,160


		ret
;=============================================================
clear_row:	push bx
		push dx

		mov dx,BACK_GROUND_COLOR

		mov cx,14

clearRow:	mov es:[bx],dx
		add bx,2
		loop clearRow


		pop dx
		pop bx
		ret
;=============================================================
get_row:	cmp byte ptr es:[bx],'1'
		je getRow	
		sub bx,2
		jmp get_row
		
getRow:		add bx,2

		cmp bx,BLOCK_HIGH
		jnb getRowRet

		mov BLOCK_HIGH,bx
		;mov word ptr es:[bx],5535H

getRowRet:	ret
;=============================================================
set_button_block_color:
		push bx
		
		mov cx,BLOCK_ROW
		mov dx,BUTTON_BLOCK_COLOR

setButtonBlockColor:	
		push cx
		push bx
		mov cx,BLOCK_COL

sColor:		cmp byte ptr es:[bx],1
		jne nextCol_sColor
		mov es:[bx],dx
nextCol_sColor:	add bx,2
		loop sColor

		pop bx
		pop cx
		add bx,NEXT_ROW
		loop setButtonBlockColor



		pop bx
		ret
;=============================================================
isMoveRight:	push bx

		add bx,BLOCK_COL
		add bx,BLOCK_COL
		sub bx,2

		mov cx,BLOCK_ROW

moveRight:	push cx
		push bx
		mov cx,BLOCK_COL


mRight:		cmp byte ptr es:[bx],1
		jne nextCol_mRight
		cmp byte ptr es:[bx+2],'0'
		jne noMoveRight
		jmp nextRow_mRight
nextCol_mRight:	sub bx,2
		loop mRight

nextRow_mRight:	pop bx
		pop cx
		add bx,NEXT_ROW
		loop moveRight

		pop bx
		call clear_old_block
		add bx,2
		call print_block
		ret

noMoveRight:	add sp,4
		pop bx
		;mov di,160*4 + 40*2
		;mov byte ptr es:[di],'X'
		ret
;=============================================================
isMoveLeft:	push bx

		mov cx,BLOCK_ROW
		
moveLeft:	push cx
		push bx
		mov cx,BLOCK_COL
		
mLeft:		cmp byte ptr es:[bx],1
		jne nextCol_mLeft
		cmp byte ptr es:[bx-2],'0'
		jne noMoveLeft
		jmp nextRow_mLeft
nextCol_mLeft:	add bx,2
		loop mLeft

nextRow_mLeft:	pop bx
		pop cx
		add bx,NEXT_ROW
		loop moveLeft

		pop bx
		call clear_old_block
		sub bx,2
		call print_block
		ret


noMoveLeft:	add sp,4
		pop bx
		ret


;=============================================================
clear_old_block:
		push bx

		mov cx,BLOCK_ROW
		mov dx,BACK_GROUND_COLOR

clearOldBlock:	push cx
		push bx
		mov cx,BLOCK_COL

cBlock:		cmp byte ptr es:[bx],1
		jne nextCol_cBlock
		mov es:[bx],dx
nextCol_cBlock:	add bx,2
		loop cBlock

		pop bx
		pop cx
		add bx,NEXT_ROW
		loop clearOldBlock

		pop bx
		ret
;=============================================================
change_screen_color:
		push bx
		push cx
		push es

		mov bx,0B800H
		mov es,bx

		mov bx,1
		mov cx,2000

changeScreenColor:
		inc byte ptr es:[bx]
		add bx,2
		loop changeScreenColor

		pop es
		pop cx
		pop bx
		ret




Tetris_end:	nop























;============================================================
set_new_int9:
		mov bx,0
		mov es,bx

		cli
		mov word ptr es:[9*4],OFFSET new_int9 - OFFSET Tetris + 9000H
		mov word ptr es:[9*4+2],0
		sti
		ret
;============================================================
sav_old_int9:
		mov bx,0
		mov es,bx

		push es:[9*4]
		pop es:[200H]
		push es:[9*4+2]
		pop es:[202H]

		ret
;============================================================
clear_07E00H:

		mov bx,0
		mov es,bx
		mov bx,7E00H

		mov cx,1024
		mov dx,0

clear07E00H:	mov es:[bx],dx
		add bx,2
		loop clear07E00H

		ret
;============================================================
cpy_Tetris:
		mov bx,cs
		mov ds,bx
		mov si,OFFSET Tetris

		mov bx,0
		mov es,bx
		mov di,9000H

		mov cx,OFFSET Tetris_end - OFFSET Tetris
		cld
		rep movsb
	
		ret

code ends



end start



运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Andy-wen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值