Всем привет!
Вот, решил тряхнуть стариной.
В свое время написал тетрис с использованием debug.exe и не имея под рукой хелпов. Потом перевел на асм. Зато получился самый маленький из известных мне тетрисов
. COM — что-то около 900 байт, но там байт 200 с конца можно смело откусить — в них неинициализированные данные.
Компилировал tasm-ом, но его должен понимать и masm.
Заодно проверю скрипт раскраски asm на сайте (говорят, он тормозит).
;asm Tetris - just for fun
;copyright (c) 1998 Vitali Brusentsev
.286
CSEG segment word public 'CODE'
assume CS:CSEG, DS:CSEG
org 100h
start: mov ax,13h
int 10h
newGame:call initGame
newFig: call initFigure
;---- Main game cycle
Main: call clear
call redraw
call getTime
add ax,delayTemp
mov timer,ax
cycle: mov ax,100h
int 16h
jz nokeys
xor ax,ax
int 16h
call keys
jmp short Main
nokeys: call getTime
cmp ax,timer
jl cycle
inc CoordY
mov si,offset figure
call check
jnz Main
dec CoordY
call checkLines
jmp short newFig
exit: mov ax,3
int 10h
int 20h
keys proc
mov si,offset figure
cmp ah,4bh ;left
jnz other1
dec CoordX
call check
jnz done
inc CoordX
ret
other1: cmp ah,4dh ;right
jnz other2
inc CoordX
call check
jnz done
dec CoordX
done: ret
other2: cmp ah,48h ;up
jnz other3
mov bp,offset dontCopy
call rotate
mov si,offset temp
call check
jz done
mov si,offset figure
mov bp,offset copy
call rotate
ret
other3: cmp ah,1 ;Escape
jz exit
other4: cmp ah,50h ;down
jnz done
mov [delayTemp],0
ret
keys endp
check proc
; si=check figure
; returns:
; ZR - check failed;
; NZ - check OK.
push ProcPRINT
mov ax,offset checkCell
mov ProcPRINT,ax
call drawFigure
pop ProcPRINT
ret
check endp
rand proc
mov ax,randSeed
mov cx,4e6dh
mul cx
add ax,3031h
xor dx,dx
mov randSeed,ax
idiv bx
mov ax,dx
ret
rand endp
getTime:
push ds
xor ax,ax
mov ds,ax
mov ax,word ptr ds:[46ch]
pop ds
ret
randomize:
call getTime
mov randSeed,ax
ret
delay proc
mov bx,ax
call getTime
add bx,ax
tester: call getTime
cmp ax,bx
jl tester
ret
delay endp
drawBox proc
push bp
mov bp,sp
push es
mov ax,[bp+6]
mov di,320
imul di
add ax,[bp+4]
mov di,ax
mov ax,0a000h
mov es,ax
mov al,[bp+12]
filler: mov cx,[BP+8]
rep stosb
add di,320
sub di,[bp+8]
dec word ptr [bp+10]
jnz filler
pop es
pop bp
or al,0ffh ;clear ZERO flag
ret 10
drawBox endp
clear proc
push 0f0h
push 96h
push 64h
push 14h
push 6eh
call drawBox
ret
clear endp
drawCell proc
push ax
mov di,10
push di
push di
mov ax,cx
mul di
add ax,20
push ax
mov ax,bx
mul di
add ax,110
push ax
call drawBox
ret
drawCell endp
drawFigure proc
xor ax,ax
mov count1,ax
@2: xor ax,ax
mov count2,ax
@3: mov bx,CoordX
add bx,count2
mov cx,CoordY
add cx,count1
lodsb
or al,al
jz skip
call ProcPRINT ; call PRINT procedure
jz done1
skip: inc count2
mov ax,size1
cmp count2,ax
jnz @3
inc count1
mov ax,size2
cmp count1,ax
jnz @2
or al,0ffh
done1: ret
drawFigure endp
initFigure proc
mov bx,5
call rand
mov bx,9
mul bx
add ax,offset TetrisFigures
mov si,ax
mov di,offset figure
mov cx,9
call copy ;---- copy figure
xor ax,ax
mov CoordY,ax
mov al,5
mov CoordX,ax
mov ax,delayValue
mov delayTemp,ax
ret
endp
redraw proc
push CoordX
push CoordY
; draw field
xor ax,ax
mov CoordX,ax
mov CoordY,ax
mov si,offset field
mov al,10
mov size1,ax
mov al,15
mov size2,ax
call drawFigure
pop CoordY
pop CoordX
; draw figure
mov si,offset figure
mov ax,3
mov size1,ax
mov size2,ax
jmp drawFigure
endp
rotate proc
mov cx,9
push cx
mov si,offset figure
push si
mov di,offset RotationTable
xor bx,bx
@1: mov dl,[si]
mov bl,[di]
mov [si+bx],dl
inc si
inc di
loop @1
pop di
pop cx
jmp bp ;copy or not
endp
initGame proc
call randomize
mov di,offset field
xor ax,ax
mov cx,75
cld
rep stosw ; clear field data
mov score,ax ; clear score
mov delayValue,8 ; set delay
ret
endp
copy proc
cld
rep movsb
dontCopy:
ret
endp
printCell proc
; (PRINT procedure)
push ax
mov al,10
mul cl
add bx,ax
pop ax
mov byte ptr [bx+offset field],al
ret
endp
checkCell proc
; (PRINT procedure)
xor ax,ax ;clear for MUL
cmp cl,14
ja fail
cmp bl,9
ja fail
mov al,10
mul cl
add bx,ax
test byte ptr [bx+offset field],0ffh
jz ok
fail: xor ax,ax ;fail
ret
ok: or al,0ffh ;OK
ret
endp
beep proc
;sound on
mov cx,6
next: in al,61h
or al,3
out 61h,al
mov al,10110110b
mov dx,43h
out dx,al
dec dx
mov al,cl
out dx,al
out dx,al
mov ax,1
call delay
;sound off
in al,61h
and al,11111100b
out 61h,al
loop next
ret
endp
checkLines proc
mov si,offset figure
mov ax,offset printCell
push ProcPRINT
mov ProcPRINT,ax
call drawFigure ; print figure into field
pop ProcPRINT
mov bx,offset field
mov si,149
mov dx,16
line: mov cx,10
dec dx
mov checkFlag,cl
load: test byte ptr [bx+si],0ffh
jnz not0
mov checkFlag,0
not0: dec si
jz return
loop load
test checkFlag,0ffh
jz line
pusha
call beep ; make audio/visual effect (not implemented)
popa
inc score
mov cx,si
add si,bx
lea di,[si+10]
std ; backward direction
rep movsb ; shift cells down
lea di,[si+10]
xor ax,ax
mov cl,5
rep stosw ; clear upper line
imul si,dx,10
dec si
jmp short line
return: ret
endp
ProcPRINT dw drawCell
RotationTable db 0Bh,0Dh,0Fh,07h,09h,0Bh,03h,05h,07h
TetrisFigures:
db 0,0,0
db 1,1,1
db 0,1,0
;--------
db 0,0,0
db 2,2,2
db 0,0,2
;--------
db 3,3,0
db 3,3,0
db 0,0,0
;--------
db 5,5,0
db 0,5,5
db 0,0,0
;--------
db 9,9,0
db 0,9,0
db 0,9,0
CoordX dw ?
CoordY dw ?
delayValue dw ?
delayTemp dw ?
timer dw ?
randSeed dw ?
count1 dw ?
count2 dw ?
score dw ?
size1 dw ?
size2 dw ?
field db 150 dup (?)
figure db 9 dup(?)
temp db 9 dup(?)
checkFlag db ?
ends
end start