SRC: самый маленький Tetris (ASM версия)
От: retalik www.airbandits.com/
Дата: 21.10.02 07:35
Оценка: 57 (3)
Всем привет!
Вот, решил тряхнуть стариной.
В свое время написал тетрис с использованием 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
Успехов,
Виталий.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.