Saturday 15 March 2014

Tetris Assembly Language Game full Source Code (tetris.asm)

Here I have uploaded the snapshots of my tetris game which is made is assembly language.
Below are the few screen shots.


Here is another screen shot below


The game has many features like 
  1. Changing the shape of Brick using Space button .
  2. Fast down of Brick using D button .
  3. Score Calculation .
  4. Time Calculation .
  5. Break of Bricks when 3 bricks of same color collide .

There are many more features You can discover :P . It was my assembly course project so I also didn't remember all functionality exactly :)

Below is the complete code for the Tetris Game .

Note :  The code is written for Computer x86 architecture and tested on DOSBOX and NASM .



-------------------------------  Code Starts Here -------------------------------------



[org 0x0100]
jmp main



;  Copyright ::  Farhan Maqsood
;   Phone         (+923084245492)
;   Email           farhangdon009@gmail.com
;  This is for learning Purpose
;  All code given is tested on DOSBOX





;;;;;;;;;;;;;;;;;;Data Declaration;;;;;;;;;;;;;;;;;;;;;;
;--------------------------------------------------------------
store_si:dw 0
current_shape:dw 0
symbol : db ' '
old_kbisr: dd 0
check_point:dw 0
dnt_mov:dw 0
exit_flag: db 0 ; not used
skip_p: db 0 ; check to skip print
skip_p2:db 0 ; 0 = print
skip_p3:db 0 ; 1 = stop printing
skip_p4:db 0 ; flags
current :db 1 ; current shape
flag_below: db 0 ;flag to check shape 2 below bits
flag_u_d:db 0 ;flag to check up down breaks
resume_flag: db 0 ; not used

seconds: db 0
minutes: db 0
hours: db 0
score : dw 0
timer_tick: db 0
;-----------------------------------------------------------

; ABOUT US

created_by: db 'Created By 0'
farhan_g: db 'Farhan Maqsood 1O-4O18 0'
adil: db 'Muhammad Adil 0'
haisum: db 'Haisum Abbas 0'
hamid: db 'Hamid Mahmood O7-OO620'
;-----------------------------------------------------------
; MENU INSTRUCTIONS   ;

score_board: db 'Score  0'
menu_item_1: db 'Press----> 1 To Start A New Game0'
menu_item_2: db 'Press----> 2 To Start Resume Game0'
menu_item_3: db 'Press----> 3 To exit Game0'
no_resumed: db 'There Is No Game Resumed Press Any Key To Continue0'
ending: db '  Happy Ending Game Over 0'
stop_it: db ' The Game Is Resumed Press 10'
option:db 0

inst_1: db 'Press D To Move Down Fast0'
inst_2: db 'Press Esc To Exit The Game0'

check_esc: db 0

;----------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;Main;;;;;;;;;;;;;;;;;;;;;;;;;

end_end:
call game_end


main:


         call menu ; MENU CALL

 cmp byte[exit_flag],1
 je exit_game
 mov byte[check_esc],0  ; initiall 0 bcz no exit
;-----------------------------------------------------------
;  code not used
 mov al,byte[symbol] ; symbol in al of shape
         mov ah,0x07
 mov word[check_point],ax  ; not used
;-----------------------------------------------------------
 xor ax,ax
 mov es,ax

; HOOKING INTERUPTS  KBISR AND TIMER
;-----------------------------------------------------
 mov ax,[es:9*4]
         mov word[old_kbisr],ax
 mov ax,word[es:9*4+2]
         mov word[old_kbisr+2],ax

 cli
 mov word[es:8*4],timer
 mov word[es:8*4+2],cs

 sti

 cli
 mov word[es:9*4],kbisr
 mov word[es:9*4+2],cs
 sti



 call clrscr
 call boundry
 jmp start
;-------------------------------------------------------

; START OF GAME  MAIN LOOP


start:

         mov byte[skip_p],0
 mov byte[skip_p2],0
 mov byte[skip_p3],0
 mov byte[skip_p4],0
 mov byte[resume_flag],0
mov byte[check_esc],0
 mov cx,18
 call initiator

; MINI LOOP OF GAME FOR SLOW DROP DOWN
pp:


         cmp byte[check_esc],1
 je end_end



 call beep ; BEEP SOUND ON EVERY DROP
 call delay ; DELAY FOR DROP
 cmp byte[current],1 ; CURRENT SHAPE
 je display1
 cmp byte[current],2
 je display2

 cmp byte[current],3
 je display3

 cmp byte[current],4
 je display4

 jmp start

display1: ; DISPLAY SHAPE 1

         call clear_shape1
 add word[store_si],160
 cmp byte[skip_p],1
 je start
 call print_shape1
 jmp pp
 ;loop pp

display2: ; DISPLAY SHAPE 2

         call clear_shape2
 add word[store_si],160
 cmp byte[skip_p2],1
 je start
 call print_shape2
 jmp pp

display3: ; DISPLAY SHAPE 3

         call clear_shape3
 add word[store_si],160
 cmp byte[skip_p3],1
 je start
 call print_shape3
 jmp pp

display4: ; DISPLAY SHAPE 4

         call clear_shape4
 add word[store_si],160
 cmp byte[skip_p4],1
 je start
 call print_shape4
 jmp pp

 jmp start

;--------------------------------------------------

exit_game:
         call clrscr

 mov si,360
 add si,160
 push si
 mov bx,ending
 push bx

 call print_string

 mov ax,[old_kbisr]
         mov bx,[old_kbisr+2]

         cli
 mov word[es:9*4],ax
 mov word[es:9*4+2],bx
 sti


 mov ax,0x4c00
 int 21h

;-------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DELAY FUNCTION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

delay:
         push ax
 push bx
 push cx
 mov ax,500
 mov bx,500
lop1:

         mov cx,ax
 dec ax
 cmp ax,0
 je exit_delay

lop2:

         dec bx
 cmp bx,0
 jne lop2
 mov bx,2000

 jmp lop1

exit_delay:
         pop cx
 pop bx
 pop ax
 ret
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;------------------------------------------------------------
; PRINT SHAPE 1
;------------------------------------------------------------
print_shape1:    ;   ****


push ax
push bx
push cx
push dx
push si

mov cx,4

mov ax,0xb800
mov es,ax
mov si,word[store_si]        ;   ****
mov al,byte[symbol]
        mov ah,0x07

mov ah,74
mov word[es:si],ax
add si,2 ; First Two Bits
mov ah,74
mov word[es:si],ax
;;;;;;;;;;;;;;;;;;;;
        add si,2
mov ah,58
mov word[es:si],ax
add si,2
mov ah,58
mov word[es:si],ax
;;;;;;;;;;;;;;;;;;;;


        pop si
pop dx
pop cx
pop bx
pop ax

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;------------------------------------------------------------
; CLEAR SHAPE 1
;------------------------------------------------------------

clear_shape1:

        push ax
push bx
push cx
push dx
push si



mov cx,4

mov ax,0xb800
mov es,ax
mov si,word[store_si]        ;   ****
mov al,0x20
mov ah,0x07

mov dx,0x0720
sub si,2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
c_s1_test:
        add si,2
cmp cx,0
je cc
dec cx
cmp word[es:si+160],0x0720
je c_s1_test

mov byte[skip_p],1
jmp skip_clear
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cc:
mov si,word[store_si]
mov cx,4

c_s1_lop:

mov word[es:si],ax
add si,2

loop c_s1_lop
jmp  end_s1

skip_clear:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Break The Bricks----->> Up-Down
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov cx,4
mov si,word[store_si]

up_down_break_s1:

mov dx,word[es:si+160]
mov bx,word[es:si+320]

cmp word[es:si],dx
jne skip_down_s1
cmp word[es:si],bx
jne skip_down_s1

mov word[es:si+160],0x0720
mov word[es:si+320],0x0720
mov word[es:si],0x0720

add word[score],1

skip_down_s1:

add si,2
loop up_down_break_s1





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Break The Bricks----->> Left-Right
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov si,word[store_si]
mov cx,4 ; to check all the indexes of the current brick
sub si,2
check_bit:

add si,2
mov dx,word[es:si+2]
mov bx,word[es:si-2]

cmp word[es:si],dx
je c_l_b
jmp skip_to_next

c_l_b:
cmp word[es:si],bx
jne skip_to_next

mov ax,si

remove_all_with_same_color_on_right:

cmp word[es:si],dx
jne r_l ; remove left (abbreviation)
mov word[es:si],0x0720
add si,2
add word[score],1
jmp remove_all_with_same_color_on_right

r_l:
mov si,ax
sub si,2

remove_all_with_same_color_on_left:

cmp word[es:si],bx
jne skip_to_next

mov word[es:si],0x0720
sub si,2
add word[score],1
jmp remove_all_with_same_color_on_left


skip_to_next:

loop check_bit

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

end_s1:

pop si
pop dx
pop cx
pop bx
pop ax

ret

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;------------------------------------------------------------
; INITIATOR FUNCTION
;------------------------------------------------------------
initiator:

mov word[store_si],20
call print_shape1
mov byte[current],1

ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;------------------------------------------------------------
; RESUME GAME
;------------------------------------------------------------
resume_the_whole_game:


push ax
;push bx
;push cx
;push dx
;push si
;push es

;start_resume:

;mov si,102
;add si,320
;add si,320
;push si

;mov bx,stop_it
;push bx

;call print_string
;mov ax,0

mov ah,0
int 0x16

;cmp al,0x31 ; ascii of R
;je end_res
;jmp start_resume


end_res:
mov byte[resume_flag],0
;pop es
;pop si
;pop dx
;pop cx
;pop bx
pop ax

ret

;------------------------------------------------------------
; kBISR sTART
;------------------------------------------------------------

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;Kbisr;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

kbisr:

push ax
push bx
push si

mov ax,0xb800
mov es,ax

mov ax,0
in al, 0x60

cmp al,0x13
jne switche_when_req

mov byte[resume_flag],1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK FOR DOWN FAST_____?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

switche_when_req:

cmp al,0x20
jne switch_shapes

cmp byte[current],1
je down_display1

cmp byte[current],2
je down_display2

cmp byte[current],3
je down_display3

cmp byte[current],4
je down_display4

down_display1:
mov si,[store_si]
add si,160
cmp word[es:si],0x0720
jne switch_shapes

call clear_shape1
add word[store_si],160
call print_shape1


jmp switch_shapes

down_display2:
mov si,[store_si]
;add si,320
cmp word[es:si+320],0x0720
jne switch_shapes

call clear_shape2
add word[store_si],160
call print_shape2

jmp switch_shapes

down_display3:

mov si,[store_si]
add si,4
add si,320
cmp word[es:si],0x0720
jne switch_shapes

call clear_shape3
add word[store_si],160
call print_shape3


jmp switch_shapes


down_display4:

mov si,[store_si]
add si,480
cmp word[es:si],0x0720
jne switch_shapes

call clear_shape4
add word[store_si],160
call print_shape4


jmp switch_shapes

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   SWITCHING OF SHAPE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
switch_shapes:
cmp al,0x39
jne lef
mov bl,[current]

cmp bl,1
je old_clear1

cmp bl,2
je old_clear2

cmp bl,3
je old_clear3

cmp bl,4
je old_clear4

jmp switched

old_clear1:
call clear_shape1
call print_shape2
jmp switched


old_clear2:
call clear_shape2
call print_shape3
jmp switched

old_clear3:
call clear_shape3
call print_shape4
jmp switched


old_clear4:
call clear_shape4
call print_shape1
jmp switched

switched:
inc byte[current]
cmp byte[current],4
ja reset

jmp lef

reset:
mov byte[current],1

; CHECK FOR LEFT BUTTON PRESSED ______?

lef:
cmp al,4bh
jne next

cmp byte[current],1
je left_display1

cmp byte[current],2
je left_display2

cmp byte[current],3
je left_display3

cmp byte[current],4
je left_display4

left_display1:
mov si,[store_si]
sub si,2
cmp word[es:si],0x0720
jne next

call clear_shape1
sub word[store_si],2
call print_shape1

jmp next

left_display2:
mov si,[store_si]
sub si,2
cmp word[es:si],0x0720
jne next

call clear_shape2
sub word[store_si],2
call print_shape2

jmp next

left_display3:
mov si,[store_si]
sub si,2
cmp word[es:si],0x0720
jne next

call clear_shape3
sub word[store_si],2
call print_shape3

jmp next

left_display4:
mov si,[store_si]
sub si,2
cmp word[es:si],0x0720
jne next

call clear_shape4
sub word[store_si],2
call print_shape4

; CHECK FOR RIGHT BUTTON PRESSED_____?

next:

cmp al,0x4d
jne exit_check

cmp byte[current],1
je right_display1
cmp byte[current],2
je right_display2

cmp byte[current],3
je right_display3

cmp byte[current],4
je right_display4

right_display1:

mov si,[store_si]
add si,8
cmp word[es:si],0x0720
jne exit_check

call clear_shape1
add word[store_si],2
call print_shape1
;mov word[right],1
jmp exit_check

right_display2:

mov si,[store_si]
add si,4
cmp word[es:si],0x0720
jne exit_check

call clear_shape2
add word[store_si],2
call print_shape2
;mov word[right],1
jmp exit_check

right_display3:

mov si,[store_si]
add si,6
cmp word[es:si],0x0720
jne exit_check

call clear_shape3
add word[store_si],2
call print_shape3
;mov word[right],1
jmp exit_check

right_display4:

mov si,[store_si]
add si,2
cmp word[es:si],0x0720
jne exit_check

call clear_shape4
add word[store_si],2
call print_shape4
;mov word[right],1
jmp exit_check

; CHECK FOR EXIT BUTTON_____?

exit_check:
cmp al , 0x01
jne exit_kbisr
mov byte[check_esc],1

exit_kbisr:

mov al, 0x20
out 0x20, al

pop si
pop bx
pop ax
iret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; subroutine to clear the screen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
clrscr:
push es
push ax
push di
mov ax, 0xb800
mov es, ax ; point es to video base
mov di, 0 ; point di to top left column
nextloc: mov word [es:di], 0x0720 ; clear next char on screen
add di, 2 ; move to next screen location
cmp di, 4000 ; has the whole screen cleared
jne nextloc ; if no clear next position
pop di
pop ax
pop es
ret
;------------------------------------------------------------
; Create Boundry
;------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; create boundry
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

boundry:


push ax
push bx
push cx
push dx
push si



mov ax,0xb800
mov es,ax
mov si,0

mov al,' '
mov ah,83

mov cx,20

b_loop:

mov word[es:si],ax
add si,80
mov word[es:si],ax

add si,80

loop b_loop

mov cx,41

mov al,' '
mov ah,83

b_loop2:

mov word[es:si],ax
add si,2
loop b_loop2



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov si,110
add si,160
mov bx,created_by
push si
push bx
call print_string


add si,156
mov bx,farhan_g
push si
push bx
call print_string

add si,160
mov bx,adil
push si
push bx
call print_string

add si,160
mov bx,haisum
push si
push bx
call print_string



add si,160
mov bx,hamid
push si
push bx
call print_string


pop si
pop dx
pop cx
pop bx
pop ax

ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SHAPE 2 Print
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print_shape2:
push ax
push bx
push cx
push dx
push si

mov cx,4


mov ax,0xb800
mov es,ax
mov si,word[store_si]        ;   ****
mov al,byte[symbol]
mov ah,0x07


mov ah ,74
mov word[es:si],ax
add si,2
mov ah ,74
mov word[es:si],ax
sub si,2
mov ah ,58
mov word[es:si+160],ax
add si,2
mov ah ,58
mov word[es:si+160],ax


pop si
pop dx
pop cx
pop bx
pop ax

ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Clear Shape2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

clear_shape2:

push ax
push bx
push cx
push dx
push si



mov cx,2

mov ax,0xb800
mov es,ax
mov si,word[store_si]        ;   ****
mov al,0x20
mov ah,0x07

mov dx,0x0720
sub si,2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
c_s2_test:
add si,2
cmp cx,0
je cc2
dec cx
cmp word[es:si+320],0x0720
je c_s2_test

mov byte[skip_p2],1
jmp skip_clear2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


cc2:
mov si,word[store_si]

mov word[es:si],ax
add si,2
mov word[es:si],ax
sub si,2
mov word[es:si+160],ax
add si,2
mov word[es:si+160],ax

jmp end_s2

skip_clear2:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Break The Bricks part 2------->> Up-Down
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov si,word[store_si]
;mov cx,2 ; to check all the indexes of the current brick


chk_blw_s2_bits_u_d:

mov cx,2 ; to check all the indexes of the current brick
sub si,2

check_bit_s2_abv_u_d:

add si,2
mov dx,word[es:si+160]
mov bx,word[es:si+320]

cmp word[es:si],dx
jne skip_this_byte

cmp word[es:si],bx ;-------------
jne skip_this_byte

mov word[es:si],0x0720
mov word[es:si+160],0x0720
mov word[es:si+320],0x0720
add word[score],1
skip_this_byte:


loop check_bit_s2_abv_u_d

cmp byte[flag_u_d],1
je done_with_this

mov byte[flag_u_d],1
mov si,word[store_si]
add si,160

jmp chk_blw_s2_bits_u_d

done_with_this:

mov byte[flag_u_d],0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Break The Bricks part 2------->> Left-Right
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov si,word[store_si]
mov cx,2 ; to check all the indexes of the current brick


chk_blw_s2_bits:

mov cx,2 ; to check all the indexes of the current brick
sub si,2

check_bit_s2_abv:

add si,2
mov dx,word[es:si+2]
mov bx,word[es:si-2]

cmp word[es:si],dx
je c_l_b_s2

jmp skip_to_next_s2

c_l_b_s2:
cmp word[es:si],bx ;-------------
jne skip_to_next_s2

mov ax,si
remove_all_with_same_color_on_right_s2:

cmp word[es:si],dx
jne r_l_s2 ; remove left (abbreviation)

mov word[es:si],0x0720
add si,2
add word[score],1
jmp remove_all_with_same_color_on_right_s2

r_l_s2:
mov si,ax
sub si,2
remove_all_with_same_color_on_left_s2:

cmp word[es:si],dx
jne skip_to_next_s2

mov word[es:si],0x0720
sub si,2
add word[score],1
jmp remove_all_with_same_color_on_left_s2


skip_to_next_s2:

loop check_bit_s2_abv

cmp byte[flag_below],1
je end_s2

mov byte[flag_below],1
mov si,[store_si]
add si,160

jmp chk_blw_s2_bits
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

end_s2:

mov byte[flag_below],0

pop si
pop dx
pop cx
pop bx
pop ax

ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;              BEEP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
beep:

push ax
push bx
push cx
push dx


mov     al, 182         ; Prepare the speaker for the
out     43h, al         ;  note.
mov     ax, 9121        ; Frequency number (in decimal)
;  for middle C.
out     42h, al         ; Output low byte.
mov     al, ah          ; Output high byte.
out     42h, al
in      al, 61h         ; Turn on note (get value from
;  port 61h).
or      al, 00000011b   ; Set bits 1 and 0.
out     61h, al         ; Send new value.
mov     bx, 25          ; Pause for duration of note.
.pause1:
mov     cx, 6535
.pause2:
dec     cx
jne     .pause2
dec     bx
jne     .pause1
in      al, 61h         ; Turn off note (get value from
;  port 61h).
and     al, 11111100b   ; Reset bits 1 and 0.
out     61h, al         ; Send new value.

pop dx
pop cx
pop bx
pop ax

ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; print string takes offset and start of string
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print_string:

push bp
mov bp,sp

push ax
push bx
push cx
push dx

push si
push di
push es


mov ax,0xb800
mov es,ax
mov di,0
mov bx,[bp+4]
mov ah,0x06

mov si,[bp+6]

loop_print:

mov al,byte[bx+di]
inc di
cmp al,0x30
je print_end

mov word[es:si],ax
add si,2
jmp loop_print


print_end:

pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop bp

ret 4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MENU
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

menu:

push ax
push bx
push si

start_menu:
call clrscr


mov si,360
push si
mov bx,menu_item_1
push bx

call print_string



add si,320
push si
mov bx,menu_item_2
push bx

call print_string




add si,320
push si
mov bx,menu_item_3
push bx

call print_string

mov ah,0
int 0x16

cmp al,0x31
je start_new_game

cmp al,0x32
je resume_game

cmp al,0x33
je exit_game_forever

jmp start_menu

start_new_game:
jmp end_menu

resume_game:
call clrscr
mov si,360
push si
mov bx,no_resumed
push bx
call print_string
mov ah,0
int 0x16
jmp start_menu

exit_game_forever:

mov byte[exit_flag],1

end_menu:

pop si
pop bx
pop ax


ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


timer:

push ax
push bx
push cx
push dx
push si
push es

mov ax,0xb800
mov es,ax
mov si,100
add si,640
add si,320
add si,320


cmp byte[check_esc],1
jne go_on

call clrscr
call game_end
mov ah,0
int 0x16

jmp end_timer
go_on:

inc byte[timer_tick]

cmp byte[timer_tick],18
jne end_timer

mov byte[timer_tick],0

inc_second:

inc byte[seconds]
cmp byte[seconds],60
jne end_timer

inc_minutes:
mov byte[seconds],0
inc byte[minutes]
cmp byte[minutes],60
jne end_timer

inc_hours:
mov byte[minutes],0
inc byte[hours]
cmp byte[hours],12
jne end_timer

mov byte[hours],0

end_timer:

mov ax,0

push si
mov al,byte[hours]
push ax
call printnum
;---------------------mov word[es:si],ax

add si,2
mov al,':'
mov ah,0x06
mov word[es:si],ax

mov ax,0
add si,2
mov al,byte[minutes]
push si
push ax

call printnum
;;;;;;;;;;;;;;;;;;;;;;;mov word[es:si],ax

add si,2
mov al,':'
mov ah,0x86
mov word[es:si],ax

mov ax,0
add si,2
mov word[es:si],0x0720 ;---- changing here
mov al,byte[seconds]
push si
push ax

call printnum
;----------------------mov word[es:si],ax

;mov si,120
add si,300


mov ax,word[score]

push si
push score_board
call print_string

add si,16
push si
push ax

call printnum
;-------------------mov word[es:si],ax

sub si,16

add si,480
push si
mov bx,inst_1
push bx
call print_string

add si,160
push si
mov bx,inst_2
push bx
call print_string

mov al, 0x20
out 0x20, al

pop es
pop si
pop dx
pop cx
pop bx
pop ax

iret



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PRINT_NUM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; subroutine to print a number at top left of screen
; takes the number to be printed as its parameter
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

printnum:

push bp
mov bp, sp
push es
push ax
push bx
push cx
push dx
push di
mov ax, 0xb800
mov es, ax ; point es to video base
mov ax, [bp+4] ; load number in ax
mov bx, 10 ; use base 10 for division
mov cx, 0 ; initialize count of digits
nextdigit: mov dx, 0 ; zero upper half of dividend
  div bx ; divide by 10
  add dl, 0x30 ; convert digit into ascii value
  push dx ; save ascii value on stack
  inc cx ; increment count of values
  cmp ax, 0 ; is the quotient zero
  jnz nextdigit ; if no divide it again
  mov di, word[bp+6] ; point p_p


nextpos: pop dx ; remove a digit from the stack
mov dh, 0x06 ; use normal attribute
mov [es:di], dx ; print char on screen
add di, 2 ; move to next screen location
loop nextpos ; repeat for all digits on stack
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop bp
ret 4

;--------------------------------------------------------
; Shape 3
;--------------------------------------------------------

print_shape3:

push ax
push si
push es


mov ax,0xb800
mov es,ax

mov si,word[store_si]

mov al,byte[symbol]
mov ah,74

mov word[es:si],ax

add si,2
mov word[es:si],ax

add si,2
mov ah,58
mov word[es:si],ax

add si,160
mov word[es:si],ax


pop es
pop si
pop ax

ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; c_s_3

clear_shape3:

push ax
push bx
push cx
push dx

push si
push es

mov si,word[store_si]
cmp word[es:si+160],0x0720
jne skip_clear_s3

add si,2


cmp word[es:si+160],0x0720
jne skip_clear_s3

;add si,2


;cmp word[es:si+160],0x0720
;jne skip_clear_s3



mov si,word[store_si]
add si,4
add si,320


cmp word[es:si],0x0720
jne skip_clear_s3



mov si,[store_si]

mov word[es:si],0x0720
add si,2
mov word[es:si],0x0720
add si,2
mov word[es:si],0x0720
add si,160
mov word[es:si],0x0720

jmp end_c_s3

skip_clear_s3:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


mov byte[skip_p3],1

end_c_s3:

pop es
pop si
pop dx
pop cx
pop bx
pop ax

ret





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Shape 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print_shape4:


push ax
push bx
push cx
push dx

push si
push es


mov ax,0xb800
mov es,ax

mov si,word[store_si]

mov al,byte[symbol]
mov ah,58
mov cx,3

mov word[es:si],ax

add si,160
mov ah,74

mov word[es:si],ax

add si,160
mov ah,58
mov word[es:si],ax


pop es
pop si
pop dx
pop cx
pop bx
pop ax

ret



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


clear_shape4:

push ax
push bx
push cx
push dx

push si
push es




mov si,[store_si]
add si,480
;add si,160

cmp word[es:si],0x0720

jne  skip_shape4_print

mov si,[store_si]

mov word[es:si],0x0720
add si,160

mov word[es:si],0x0720

add si,160

mov word[es:si],0x0720

jmp end_shape4


skip_shape4_print:

mov byte[skip_p4],1

end_shape4:

pop es
pop si
pop dx
pop cx
pop bx
pop ax

ret

game_end:

push ax
push es
push bx
push si

mov ax,0xb800
mov es,ax
call clrscr

mov si,60
add si,640
push si
mov bx,ending
push bx

call print_string

pop si
pop bx
pop es
pop ax

;mov ax,0x4c00
;int 21h

ret




-----------------   Code Completes Here --------------------------------------


Copy the above code and compile and run it, If you have any queries then let me know. Thanks


1 comment: