Tetris

Opět jedna známá hra. Jediné, co je na ní zajímavé, je velikost programového souboru, která je díky Assembleru jen 937 bytů.
Přitom podporuje všechny standardní funkce, jako otáčení kostek (Enter), pausu (P), zobrazení příští kostky, nebo ukládání rekordu do samotného COM-souboru. Vytvořeno zhruba v letech 1997-1998.
Použité technologie:
Download:
.286
_TEXT segment
  assume cs:_TEXT , ds:_TEXT , es:_TEXT , ss:_TEXT

  org 100h
@filename:
  mov sp,offset endstack

  mov ax,00001h
  int 10h

  mov ah,1
  mov cx,02000h
  int 10h

 newgame:
  mov ax,score
  cmp ax,Srecord
  jb norecord
  mov Srecord,ax
 norecord:
  mov score,0

  push ds
  xor ax,ax
  mov ds,ax
  mov si,046Ch
  mov di,offset Rseed
  lodsw
  stosw
  pop ds

  call makerand
  mov next,si

  mov di,offset plocha2
  mov cx,plochay
  mov ax,0E007h
  cld
  rep stosw
  mov cl,3
  mov ax,0FFFFh
  rep stosw

 newcycle:
  mov bx,100
 findline:
  cld
  mov ax,0FFFFh
  mov di,offset plocha2
  mov cx,plochay
  repnz scasw
  jnz noline
  std
  sub di,2
  mov si,di
  sub si,2
  sub cx,plochay
  not cx
  dec cx
  rep movsw
  add score,bx
  shl bx,1
  jmp findline

 noline:
  mov al,ispeed
  mov ah,byte ptr [score+1]
  shr ah,3
  sub al,ah
  jnc plus
  mov al,1
 plus:
  mov speed,al
  mov ticks,al

  mov bx,RValue
  mov ax,RSeed
  rol ax,3
  sub ax,7
  xor ax,bx
  mov RValue,ax
  mov RSeed,bx

  call makerand

  xchg next,si

  mov dx,7
  xor bx,bx
  xor bp,bp
  call putblock
  jnc back
  jmp newgame

 put:
  call putblock
  jc cycle
 back:
  mov actblock,si
  mov actrot,bp
  mov actx,dx
  mov acty,bx

  call redraw

 cycle:

  mov dx,actx
  mov bx,acty
  mov si,actblock
  mov bp,actrot

  mov ah,01h
  int 16h
  jz nokey
  xor ah,ah
  int 16h
  cmp ah,04Bh
  je left
  cmp ah,04Dh
  je right
  cmp ah,050h
  je down
  cmp al,0Dh
  je rotate
  cmp al,1Bh
  je escape
  cmp ah,19h
  je pause
 nokey:
  push es
  xor ax,ax
  mov es,ax
  mov al,lasttick
  mov ah,es:[046Ch]
  pop es
  cmp ah,al
  mov lasttick,ah
  je cycle
  dec ticks
  cmp ticks,0
  ja cycle
  mov al,speed
  mov ticks,al
  dec score
 down:
  add score,2
  inc bx
  call putblock
  jnc back
  dec bx
  call putblock
  clc
  call plochaXtoY
  jmp newcycle

 left:
  cmp dx,0
  je cycle
  dec dx
  jmp put

 right:
  cmp dx,plochax+3
  jae cycle2
  inc dx
  jmp put

 rotate:
  add bp,2
  and bp,00007h
  jmp put

 pause:
  mov ah,0
  int 16h
 cycle2:
  jmp cycle

 escape:
  mov ah,1
  mov cx,00D0Eh
  int 10h
  mov ax,00003h
  int 10h

  mov ax,word ptr ds:[2Ch]          ; AX - segment prostredi DOSu
  mov ds,ax                         ;    -> DS
  xor si,si                         ; hledame 0000h od zacatku
  mov cx,0FFFFh                     ; maximalne FFFFh bytu
FAloop:
  lodsw                             ; DS:SI -> AX ; zaroven add si,2
  cmp ax,0000h
  je FAfound
  dec si
  loop FAloop                       ; sniz CX a vrat se pokud <> 0
  jmp exit
FAfound:
  add si,2                          ; zkopirujeme z DS:SI na ES(nase):[EXEfile]
  mov dx,si
  mov ax,03D01h
  int 21h
  mov bx,cs
  mov ds,bx
  jc exit
  mov bx,ax
  xor cx,cx
  mov dx,offset Srecord-100h
  mov ax,04200h
  int 21h
  mov dx,offset Srecord
  mov cx,2
  mov ah,40h
  int 21h
  mov ah,3Eh
  int 21h

 exit:
  mov ax,04C00h
  int 21h

putbits proc near
  PBloop:
    mov ah,00h
    shl bx,1
    jnc PBdal
    mov ah,0Fh
   PBdal:
    stosw
   loop PBloop
   dec dh
  ret
putbits endp

redraw proc near
  push es
  mov ax,0B800h
  mov es,ax

  mov ah,09h
  mov si,offset text1
  mov di,2*(text1x+40*text1y)
  mov cx,text1l
  call puttext
  mov si,offset text2
  mov di,2*(text2x+40*text2y)
  mov cx,text2l
  call puttext
  mov ah,14
  mov si,offset text3
  mov di,2*(text3x+40*text3y)
  mov cx,text3l
  call puttext
  mov ah,12
  mov si,offset text4
  mov di,2*(text4x+40*text4y)
  mov cx,text4l
  call puttext
  mov ah,02
  mov si,offset text5
  mov di,2*(text5x+40*text5y)
  mov cx,text5l
  call puttext

  mov ax,score
  mov bh,14
  mov di,2*(scorex+scorey*40)
  call put10

  mov ax,Srecord
  mov bh,12
  mov di,2*(recordx+recordy*40)
  call put10

  mov ax,002DBh
  cld
  mov cx,plochax+2
  mov di,2*vplochax
  rep stosw
  mov cx,plochax+2
  mov di,2*(vplochax+40*(plochay+1))
  rep stosw

  mov si,offset plocha1
  mov di,(40+vplochax)*2
  mov dh,plochay
 Rloop1:
   mov cx,plochax
   lodsw
   mov bx,ax
   shl bx,3
   mov ax,002DBh
   stosw
   call putbits
   mov ah,02
   stosw
   add di,2*(40-plochax-2)
   cmp dh,0
  jne Rloop1

   mov si,offset kostky
   add si,next
   mov di,2*(40*nexty+nextx)
   mov dh,4
   mov bx,[si]
   mov al,0DBh
  Rloop4:
   mov cx,4
   call putbits
   add di,2*(40-4)
   cmp dh,0
  jne Rloop4

  pop es
  ret
redraw endp

plochaXtoY proc near
  push si
  mov si,offset plocha2
  mov di,offset plocha1
  jc p2to1
  xchg si,di
 p2to1:
  mov cx,plochay+3
  cld
  rep movsw
  pop si
  ret
plochaXtoY endp

putblock proc near ;  [kostky+si+bp]=offset of block  DX,DL=x  BX=y
  pusha
  stc
  call plochaXtoY
  mov di,offset plocha1
  shl bx,1
  add di,bx
  mov bx,[kostky+si+bp]
  mov si,di
  mov ch,4
  mov cl,dl
  cld
 Ploop1:
   lodsw

   mov dh,bh
   and dx,0F000h
   shl bx,4
   shr dx,cl
   test ax,dx
   jnz over
   or ax,dx

   stosw
   dec ch
   cmp ch,0
 jne Ploop1
  clc
  jmp Pend
 over:
  stc
  call plochaXtoY
 Pend:
  popa
  ret
putblock endp

makerand proc near
  xor dx,dx
  mov cx,kostek
  div cx
  shl dx,3
  mov si,dx
  ret
makerand endp

put10 proc near ; AX-number BH-color ES:DI-output - end (!)
  mov cx,10
  mov bl,5
 P10loop:
  xor dx,dx
  div cx
  add dl,48
  mov dh,bh
  mov es:[di],dx
  sub di,2
  dec bl
  cmp bl,0
  jne P10loop
  ret
put10 endp

puttext proc near ; SI,DI,CX,AH
 PTloop:
  lodsb
  stosw
  loop PTloop
  ret
puttext endp

dat:
 kostek = 15
 kostky dw 0CC00h ; ctverec 2x2
        dw 0CC00h
        dw 0CC00h
        dw 0CC00h
        dw 02222h ; tyc 4x1
        dw 00F00h
        dw 02222h
        dw 00F00h
        dw 04440h ; tyc 3x1
        dw 00E00h
        dw 04440h
        dw 00E00h
        dw 04400h ; tyc 2x1
        dw 0C000h
        dw 04400h
        dw 0C000h
        dw 0C800h ; male L
        dw 08C00h
        dw 04C00h
        dw 0C400h
        dw 06440h ; velke L
        dw 08E00h
        dw 044C0h
        dw 00E20h
        dw 04460h ; zrcadlove velke L
        dw 02E00h
        dw 0C440h
        dw 00E80h
        dw 00E40h ; male T
        dw 04640h
        dw 04E00h
        dw 04C40h
        dw 0E440h ; velke T
        dw 08E80h
        dw 044E0h
        dw 02E20h
        dw 04E40h ; kriz
        dw 04E40h
        dw 04E40h
        dw 04E40h
        dw 02E80h ; velke Z
        dw 0C460h
        dw 02E80h
        dw 0C460h
        dw 08E20h ; zrcadlove velke Z
        dw 064C0h
        dw 08E20h
        dw 064C0h
        dw 02640h ; male Z
        dw 00C60h
        dw 02640h
        dw 00C60h
        dw 04620h ; zrcadlove male Z
        dw 06C00h
        dw 04620h
        dw 06C00h
        dw 0EA00h ; U
        dw 0C8C0h
        dw 00AE0h
        dw 06260h
 text1l=6
 text1x=3
 text1y=2
 text1    db 'TETRIS'
 text2l=13
 text2x=0
 text2y=3
 text2    db '(C) Oto Valek'
 text3l=5
 text3x=30
 text3y=2
 text3    db 'Score'
 text4l=6
 text4x=30
 text4y=5
 text4    db 'Record'
 text5l=4
 text5x=30
 text5y=8
 text5    db 'Next'
 scorex  =31+4
 scorey  =3
 recordx =31+4
 recordy =6
 nextx   =31
 nexty   =10
 vplochax=14
 plochax =10
 plochay =20
 ispeed  =18
 blank    dw 0E007h
 score    dw 0
 Srecord  dw 0
 plocha2  dw plochay+3 dup(?)
 plocha1  dw plochay+3 dup(?)
 speed    db ?
 ticks    db ?
 next     dw ?
 actblock dw ?
 actrot   dw ?
 actx     dw ?
 acty     dw ?
 lasttick db ?
 RSeed    dw ?
 RValue   dw ?
 _stack   dw 100 dup(?)
 endstack:
_TEXT ends
END @filename