Files
assembly-project/CatchApple.asm
2022-02-25 15:55:38 +02:00

1331 lines
53 KiB
NASM

;########################################
;# #
;# Idan Cohen(17 Years old) #
;# #
;########################################
IDEAL
MODEL small
STACK 100h
DATASEG
; EQU --------------------------------
ZERO equ 0
; Colors -----------------------------
RED equ 180 ; Red color
LIGHT_BROWN EQU 198 ; Light brown color
; ------------------------------------
; Ascii ------------------------------
CARRIAGERET equ 13
;-------------------------------------
; Apples settings ----------------------
MANY_APPLES EQU 2
APPLES_START_Y equ 2
SPEED_MOVE equ 6
X_START_APPLE1 EQU 30
X_START_APPLE2 EQU 100
Y_START_APPLE2 EQU 94
APPLE_SIZE EQU 10
; --------------------------------------
; Bucket setting -----------------------
X_START_BUCKET EQU 125
Y_START_BUCKET EQU 180
X_SIZE_BUCKET EQU 50
Y_SIZE_BUCKET EQU 20
; --------------------------------------
; Time ---------------------------------
SECOND EQU 18
; --------------------------------------
; Ports --------------------------------
DIVISOR EQU 42h
SPEAKERS EQU 61h
ACCESS_SPEAKERS EQU 43h
; --------------------------------------
OBJECTS_COUNT EQU 5
SCREEN_CORNER EQU 270
PRINT_NULL_COUNT EQU 613
; Variables -----------------------------------------------------------------------------------------------------------
CountApples db ZERO,ZERO,ZERO,ZERO,'$' ; Apples count
StringNull db ZERO,'$'
; Setting for photos ------------------------------------------------------------------
ErrorMsg db 'Error','$' ; Error message
Header db 54 dup(ZERO) ; Header of photo
Palette db 256*4 dup(ZERO) ; Palette of colors(256 colors(1 color = 4 bytes))
ScrLine db 320 dup(ZERO) ; Screen line
;--------------------------------------------------------------------------------------
; Bucket -------------------
Bucket dw X_START_BUCKET,Y_START_BUCKET,X_SIZE_BUCKET,Y_SIZE_BUCKET,LIGHT_BROWN
; --------------------------
; Apples -------------------
Apple1 dw X_START_APPLE1,APPLES_START_Y+1,ZERO,APPLE_SIZE,RED
Apple2 dw X_START_APPLE2,Y_START_APPLE2+1,ZERO,APPLE_SIZE,RED
; --------------------------
; Photos --------------------------
WallpaperStart db 'start.bmp',ZERO ; Photo for start screen
WallpaperGame db 'wallgm.bmp',ZERO ; Photo for game screen
WallpaperEnd db 'TheEnd.bmp',ZERO ; Photo for end screen
WallpaperCredits db 'Credits.bmp',ZERO ; Photo for credits screen
WallpaperInstructions db 'Instru.bmp',ZERO ; Photo for instructions screen
; ---------------------------------
; Array photo -------------------------------------------------------------------------------------------------------
PhotoStartArray dw offset WallpaperStart,offset ErrorMsg,offset Header,offset Palette,offset ScrLine ; Wallpaper for start screen
PhotoCreditsArray dw offset WallpaperCredits,offset ErrorMsg,offset Header,offset Palette,offset ScrLine ; Wallpaper for credits screen
PhotoGameArray dw offset WallpaperGame,offset ErrorMsg,offset Header,offset Palette,offset ScrLine ; Wallpaper for game screen
PhotoEndArray dw offset WallpaperEnd,offset ErrorMsg,offset Header,offset Palette,offset ScrLine ; Wallpaper for end screen
PhotoInstructionsArray dw offset WallpaperInstructions,offset ErrorMsg,offset Header,offset Palette,offset ScrLine ; Wallpaper for end screen
; -------------------------------------------------------------------------------------------------------------------
; Sound ---------------------------
SoundLe dw 0a98h
; ---------------------------------
ObjectsDisplay dw OBJECTS_COUNT,offset PhotoGameArray,offset Bucket,offset Apple1,offset Apple2,offset CountApples
; --------------------------------------------------------------------------------------------------------------------
CODESEG
;########################################
;# #
;# Params: Nothing #
;# #
;# GraphicMode - change the mode to #
;# graphic mode #
;# #
;########################################
proc GraphicMode
push ax ; Backup
mov ax, 13h ; Graphic mode
int 10h
pop ax ; Restore
ret
endp GraphicMode
;########################################
;# #
;# Params: Values of X, Y and Color #
;# #
;# PutPixel - Insert pixel to screen #
;# #
;########################################
proc PutPixel ; by value
push bp ; Backup
mov bp, sp
push cx
push dx
push ax ; Finish backup
mov cx,[bp+8] ; x
mov dx,[bp+6] ; y
mov al,[bp+4] ; color
mov ah,0Ch ; Put pixel
int 10h
pop ax ; Restore
pop dx
pop cx
pop bp ; Finish restore
ret 6
endp PutPixel
;########################################
;# #
;# Params: Values of X, Y, Count, #
;# Color #
;# #
;# Vline - Draws a vertical line #
;# #
;# #
;########################################
proc VLine ; by value
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx ; Finish backup
mov ax, [bp+10] ; x start
mov bx, [bp+8] ; y start
mov cx, [bp+6] ; count
mov dx, [bp+4] ; color
VerticalDrawing:
push ax ; Push x
push bx ; Push y
push dx ; Push color
call PutPixel
inc ax ; Add 1 to ax(x)
loop VerticalDrawing
pop dx ; Restore
pop cx
pop bx
pop ax
pop bp ; Finish restore
ret 8
endp VLine
;############################################
;# #
;# Params: Array of rect #
;# #
;# #
;# PrintRect - Draws a rectangle #
;# #
;# #
;############################################
proc PrintRect ; by value
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx
push si
push di ; Finish backup
mov si, [bp+4]
mov ax, [si] ; x start
mov bx, [si+2] ; y start
mov dx, [si+4] ; x size
cmp dx, ZERO
je PrintRectExit ; If dx(x size) == 0, jump to PrintRectExit
mov cx, [si+6] ; y size
cmp cx, ZERO
je PrintRectExit ; If cx(y size) == 0, jump to PrintRectExit
mov di, [si+8] ; color
InflationDrawing:
push ax ; x start
push bx ; y start
push dx ; count
push di ; color
call VLine
inc bx ; Add 1 to bx
loop InflationDrawing
PrintRectExit:
pop di ; Restore
pop si
pop dx
pop cx
pop bx
pop ax
pop bp ; Finish Restore
ret 2
endp PrintRect
;############################################
;# #
;# Params: Array of rect #
;# #
;# #
;# MoveObjectDown - Move the rect down #
;# #
;# #
;############################################
proc MoveObjectDown ; offset of rect
push bp ; Backup
mov bp, sp
push ax
push bx
mov bx, [bp+4] ; offset of rect
mov ax, [bx+2] ; y start
add ax, SPEED_MOVE ; y start + SPEED_MOVE
mov [bx+2], ax ; Save y start
pop bx ; Restore
pop ax
pop bp ; Finish restore
ret 2
endp MoveObjectDown
;####################################################################################################
;# #
;# Params: {Count of array > offset of array wallpaper > {offset of Rects} > offset of text }(dw) #
;# #
;# #
;# UpdateDisplay - Update display of game #
;# #
;# #
;####################################################################################################
proc UpdateDisplay ; {Count of array > offset of array wallpaper > {offset of Rects} > offset of text }(dw)
push bp ; Backup
mov bp, sp
push bx
push cx ; Backup
mov bx, [bp+4] ; Offset of array of offset
mov cx, [bx] ; Count of objects in array
add bx, 2 ; bx += 2
push [bx] ; push the offset of wallpaper
call PrintPhotoByArray ; Print Photo
add bx, 2 ; bx += 2
sub cx, 2 ; cx -= 2
UpdateDisplayPrintRects: ; Loop for print rects
push [bx] ; push offset of array rect
call PrintRect ; print rect
add bx, 2 ; bx += 2
loop UpdateDisplayPrintRects
push [bx] ; push offset of text
call PrintNewString ; print text
pop cx ; Restore
pop bx
pop bp ; Finish restore
ret 4
endp UpdateDisplay
;############################################
;# #
;# Params: Offset of filename, offset #
;# of Error message #
;# #
;# OpenFile - open file #
;# #
;# #
;# Return - filehandle to stack #
;# #
;# #
;############################################
proc OpenFile ; offset Filename(ref) > offset Error message(ref)
push bp ; Backup
mov bp, sp
push ax
push dx ; Finish backup
mov ah, 3dh ; open file(for int)
xor al, al
mov dx, [bp+6] ; offset of filename
int 21h
jc openerror ; if Carry flag = 1, jmp openerror
mov [bp+6], ax ; file handle
jmp ExitOpenFile
openerror:
mov dx, [bp+4] ; offset ErrorMsg
mov ah, 9h ; print string
int 21h
ExitOpenFile:
pop dx ; Restore
pop ax
pop bp ; Finish restore
ret 2 ; Return file handle to bp+4
endp OpenFile
;############################################
;# #
;# Params: Offset of header(54 Bytes), #
;# filehandle #
;# #
;# ReadHeader - Read BMP file header #
;# #
;############################################
proc ReadHeader ; offset header(54 Bytes) > filehandle
; Read BMP file header, 54 bytes
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx ; Finish backup
mov ah, 3fh ; Read from file
mov bx, [bp+4] ; filehandle
mov cx, 54 ; size of header(bytes)
mov dx, [bp+6] ; offset header
int 21h
pop dx ; Restore
pop cx
pop bx
pop ax
pop bp ; Finish restore
ret 4
endp ReadHeader
;############################################
;# #
;# Params: Offset of palette #
;# #
;# #
;# ReadPalette - Read color to palette #
;# #
;############################################
proc ReadPalette ; offset of palette
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx ; Finish backup
mov ah, 3fh ; Read from file
mov cx, 400h ; 256 colors * 4 bytes = 400h
mov dx, [bp+4] ; offset of palette
int 21h
pop dx ; Restore
pop cx
pop bx
pop ax
pop bp ; Finish restore
ret 2
endp ReadPalette
;############################################
;# #
;# Params: Offset of palette #
;# #
;# #
;# CopyPal - copy the color from palette #
;# oppiste #
;# #
;# #
;############################################
proc CopyPal ; Offset of palette
push bp ; Backup
mov bp,sp
push ax
push cx
push dx
push si ; Finish backup
mov si, [bp+4] ; offset of palette
mov cx, 256 ; many color
mov dx, 3c8h ; starting port
xor al, al
out dx, al ; copy starting color to port 3C8h
inc dx
PalLoop:
mov al, [si+2] ; Get red value
shr al, 2 ; Max is 255, but video palette maximal
; Value is 63. Therefore dividing by 4
out dx, al
mov al, [si+1] ; Get green value
shr al, 2
out dx, al ; Sent it
mov al, [si] ; Get blue value
shr al, 2
out dx, al ; Sent it
add si, 4 ; Point to next color
; (There is null chr. after every color)
loop PalLoop
pop si ; Restore
pop dx
pop cx
pop ax
pop bp ; Finish restore
ret 2
endp CopyPal
;############################################
;# #
;# Params: Offset of Scrline #
;# #
;# #
;# CopyBitmap - copy the color to screen #
;# #
;# #
;############################################
proc CopyBitmap ; offset ScrLine
push bp ; Backup
mov bp, sp
push ax
push cx
push dx
push es
push di
push si ; Finish backup
mov ax, 0A000h ; address of video card
mov es, ax
mov cx, 200 ; Height = 200px
PrintBMPLoop:
push cx
; di = cx*320, point to he correct screen line
mov di, cx
shl cx, 6
shl di, 8
add di, cx
; Read one line
mov ah, 3fh
mov cx, 320
mov dx, [bp+4] ; offset Scrline
int 21h
; Copy one line into video memory
cld ; Clear direction flag for movsb
mov cx, 320
mov si, [bp+4] ; offset Scrline
rep movsb ; (move string byte) Update SI(si+1) and DI(di+1) until cx = 0
pop cx
loop PrintBMPLoop
pop si ; Restore
pop di
pop es
pop dx
pop cx
pop ax
pop bp ; Finish restore
ret 2
endp CopyBitmap
;############################################
;# #
;# Params: File handle #
;# #
;# #
;# CloseFile - Close file #
;# #
;# #
;############################################
proc CloseFile ; File handle
push bp ; Backup
mov bp, sp
push ax
push bx ; Finish backup
mov bx, [bp+4] ; file handle
mov ah, 3eh ; Close file
int 21h
pop bx ; Restore
pop ax
pop bp ;Finish restore
ret 2
endp CloseFile
;########################################################################################
;# #
;# Params: Offset of photo(filename), offset of error message, offset of headr, #
;# offset of palette, offset of ScrLine #
;# #
;# #
;# PrintPhoto - Print photo on screen # #
;# #
;# #
;########################################################################################
proc PrintPhoto ; offset of photo > offset of error message > offset of header > offset of palette > offset of Scrline
push bp ; Backup
mov bp, sp
push bx ; Finish backup
push [bp+12] ; offset of photo
push [bp+10] ; offset of error message
call OpenFile
pop bx ; return file handle
push [bp+8] ; offset of header
push bx ; push file handle
call ReadHeader
push [bp+6] ; offset of palette
call ReadPalette
push [bp+6] ; offset of palette
call CopyPal
push [bp+4] ; offset of Scrline
call CopyBitmap
push bx ; Push file handle
call CloseFile ; Close file
pop bx ; Restore
pop bp ; Finish restore
ret 10
endp PrintPhoto
;############################################
;# #
;# Params: Offset of string #
;# #
;# #
;# PrintNewString - print string #
;# #
;# #
;############################################
proc PrintNewString ; Offset of string
push bp ; Backup
mov bp, sp
push ax
push dx ; Finish backup
mov dl, CARRIAGERET
mov ah, 2 ; Print char
int 21h
push [bp+4]
call PrintString
pop dx ; Restore
pop ax
pop bp ; Finish restore
ret 2
endp PrintNewString
;############################################
;# #
;# Params: Offset of string #
;# #
;# #
;# PrintString - print string #
;# #
;# #
;############################################
proc PrintString ; Offset of string
push bp ; Backup
mov bp, sp
push ax
push dx ; Finish backup
mov dx, [bp+4] ; offset of string
mov ah, 9 ; Print string
int 21h
pop dx ; Restore
pop ax
pop bp ; Finish restore
ret 2
endp PrintString
;################################################
;# #
;# Params: num(val), mod(val) #
;# #
;# MathMod - Return mod(num % mod) to stack #
;# #
;################################################
proc MathMod ; Num(val) > mod(val)
push bp ; Backup
mov bp, sp
push ax
push bx
push dx ; Finish backup
mov ax, [bp+6] ; Num
mov bx, [bp+4] ; Mod
div bx ; Num / Mod
mov [bp+6], dx ; Save
pop dx ; Restore
pop bx
pop ax
pop bp ; Finish restore
ret 2
endp MathMod ; Resturn Mod
;####################################################################
;# #
;# Params: Num(val)(Minimum), Num(val)(65535(FFFF) Maximun) #
;# #
;# #
;# Random - Random until 65535(FFFF) #
;# #
;# Return - Random num to stack #
;# #
;####################################################################
proc Random ; Num(val)(minimum) > Num(val)(65535(FFFF) maximum)
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx ; Finish backup
RandomStart: ; Random start
mov cx, 4 ; Move to cx 4 for loop
RandomPushZero: ; pust to stack zero(0)
push ZERO ; ZERO = 0
loop RandomPushZero
call GetFullSystemTime ; Return time of system
pop ax ; pop hundredth(1/100)
mov cx, 3 ; Move to cx 3 for loop
RandomMul: ; Get out params and mul with ax
pop bx ; pop param
cmp bx, ZERO ; if bx == 0 so, jump to RandomNotMul
je RandomNotMul
mul bx ; mul with ax
jmp RandomMulContinue
RandomNotMul:
mov bx, 23 ; Move 23 to bx
mul bx ; ax *= bx
RandomMulContinue:
loop RandomMul
cmp ax, [bp+4]
jb RandomStart ; If ax > maximum, jump to RandomStart
push ax ; push ax for mod
push [bp+4] ; push maximun for mod
call MathMod ; Return mod
pop ax ; mod
cmp ax, [bp+6]
ja ExitRandom ; If ax > minimum, jump to ExitRandom
jmp RandomStart
ExitRandom:
mov [bp+6], ax ; Save
pop dx ; Restore
pop cx
pop bx
pop ax
pop bp ; Finish retore
ret 2
endp Random ; Return random
;########################################################
;# #
;# Params: 4x(push 0) #
;# #
;# #
;# GetFullSystemTime - Return system time #
;# #
;# Return - Hour, Minute, Second, Hundredth to stack #
;# #
;########################################################
proc GetFullSystemTime ; Hour(=0) > Minute(=0) > Second(=0) > Hundredth(=0)
push bp ; Backup
mov bp ,sp
push ax
push cx
push dx ; Finish Backup
mov ah, 2ch ; Get system time
int 21h
mov [bp+10], ch ; Save hour
mov [bp+8], cl ; Save minute
mov [bp+6], dh ; Save second
mov [bp+4], dl ; Save hundredth
pop dx ; Restore
pop cx
pop ax
pop bp ; Finish restore
ret
endp GetFullSystemTime ; Return Hour, Minute, Second, Hundredth(1/100)
;####################################################
;# #
;# Params: Num in ascii(val) #
;# #
;# #
;# AsciiToDigit - Ascii to digit #
;# #
;# #
;####################################################
proc AsciiToDigit ; Num in Ascii(val)
push bp ; Backup
mov bp, sp
push ax ; Finish backup
mov ax, [bp+4] ; Num
sub ax, 30h ; Num - 30
mov [bp+4], ax ; save num
pop ax ; Restore
pop bp ; Finish restore
ret
endp AsciiToDigit ; Return Digit
;####################################################
;# #
;# Params: Num(val) #
;# #
;# #
;# DigitToAscii - digit to ascii #
;# #
;# #
;####################################################
proc DigitToAscii ; Digit(val)
push bp ; Backup
mov bp, sp
push ax ; Finish backup
mov ax, [bp+4] ; Num
add ax, 30h ; Num + 30
mov [bp+4], ax ; save num
pop ax ; Restore
pop bp ; Finish restore
ret
endp DigitToAscii ; Return digit in ascii
;####################################################
;# #
;# Params: Offset of string(db)(start with ascii #
;# of num) #
;# #
;# AsciiToNum - Ascii to num #
;# #
;# #
;####################################################
proc AsciiToNum ; Offset of string(db)
push bp ; Backup
mov bp, sp
push ax
push bx ; Finish backup
xor ax, ax ; reset ax
mov bx, [bp+4] ; move the offset of string to bx
DaughterAsciiToNum:
mov al, [byte ptr bx] ; move the value in bx as byte(8 bits) to al
cmp al, 30h
jl ExitAsciiToNum ; if value(in al) < 30h, so jump to ExitAsciiToNum
cmp al, 39h
jg ExitAsciiToNum ; if value(in al) > 39h, so jump to ExitAsciiToNum
push ax
call AsciiToDigit
pop ax ; Get num
mov [byte ptr bx], al ; Save
inc bx ; bx++
jmp DaughterAsciiToNum ; Again
ExitAsciiToNum:
pop bx ; Restore
pop ax
pop bp ; Finish restore
ret 2
endp AsciiToNum
;####################################################
;# #
;# Params: Offset of string(db)(start with num) #
;# #
;# #
;# NumToAscii - Num to ascii #
;# #
;# #
;####################################################
proc NumToAscii ; Offset of string(db)
push bp ; Backup
mov bp, sp
push ax
push bx ; Finish backup
xor ax, ax ; reset ax
mov bx, [bp+4] ; move the offset of string to bx
DaughterNumToAscii:
mov al, [byte ptr bx] ; move the value in bx as byte(8 bits) to al
cmp al, 0
jl ExitNumToAscii ; if value(in al) < 0, so jump to ExitAsciiToNum
cmp al, 9
jg ExitNumToAscii ; if value(in al) > 9, so jump to ExitAsciiToNum
push ax
call DigitToAscii
pop ax ; Get num
mov [byte ptr bx], al ; Save
inc bx ; bx++
jmp DaughterNumToAscii ; Again
ExitNumToAscii:
pop bx ; Restore
pop ax
pop bp ; Finish restore
ret 2
endp NumToAscii
;####################################################
;# #
;# Params: Offset of photo array(dw) #
;# #
;# #
;# PrintPhotoByArray - Print photo #
;# #
;# #
;####################################################
proc PrintPhotoByArray ; Offset of photo array(dw)
; {offset of filename > offset of ErrorMsg > offset of Header > offset of Palette > offset of ScrLine }
push bp ; Backup
mov bp, sp
push bx ; Finish backup
mov bx, [bp+4] ; photo array
push [bx] ; filename
push [bx+2] ; Error message
push [bx+4] ; Header
push [bx+6] ; Palette
push [bx+8] ; ScrLine
call PrintPhoto
pop bx ; Restore
pop bp ; Finish restore
ret 2
endp PrintPhotoByArray
;####################################################
;# #
;# Params: x(=0) > y(=0) for return #
;# #
;# #
;# GetLocationMouse - Get location of mouse #
;# #
;# Return - x, y to stack #
;# #
;####################################################
proc GetLocationMouse ; x(=0) > y(=0) for return
push bp ; Backup
mov bp, sp
push ax
push bx
push cx
push dx ; Finish backup
mov ax, 3 ; for interupt
int 33h
mov [bp+6], cx ; x of location
mov [bp+4], dx ; y of location
pop dx ; Restore
pop cx
pop bx
pop ax
pop bp ; Finish restore
ret
endp GetLocationMouse ; Return x(dw), y(dw)
;####################################################
;# #
;# Params: Nothing #
;# #
;# #
;# ResetMouse - Reset mouse #
;# #
;# #
;####################################################
proc ResetMouse
push ax ; Backup
mov ax, 0 ; for interupt
int 33h
pop ax ; Restore
endp ResetMouse
;####################################################
;# #
;# Params: param(=0) for return #
;# #
;# #
;# GetSystemTime - Get time of system(clock) #
;# #
;# Return - time of system to stack #
;# #
;####################################################
proc GetSystemTime ; param(=0) for return
push bp ; Backup
mov bp, sp
push ax
push es ; Finish backup
mov ax, 40h ; port
mov es, ax
mov ax,[es:6ch] ; clock
mov [bp+4], ax
pop es ; Restore
pop ax
pop bp ; Finish restore
ret
endp GetSystemTime ; Return time
;####################################################
;# #
;# Params: Seconds / 0.055(dw)(Unsigned) #
;# #
;# #
;# Delay - Delay(waiting) #
;# #
;# #
;####################################################
proc Delay ; Seconds / 0.055(dw)(Unsigned)
push bp ; Backup
mov bp, sp
push ax
push cx
push dx ; Finish backup
mov ax, [bp+4] ; Seconds
push 0 ; for proc
call GetSystemTime
pop cx ; First time
push 0 ; for proc
call GetSystemTime
pop dx ; Second time
push cx ; Backup first time
sub dx, cx ; Second time - first time
DelayCheck:
cmp dx, ax ; 10 sec (0.055 sec * 182 = 10 sec)
ja ExitDelay ; if dx > ax, jamp to ExitDelay
push 0 ; for proc
call GetSystemTime
pop dx ; Update second time
pop cx ; Restore first time
push cx ; Backup first time
sub dx, cx ; Second time - first time
jmp DelayCheck
ExitDelay:
pop cx
pop dx ; Restore
pop cx
pop ax
pop bp ; Finish
ret 2
endp Delay
;####################################################
;# #
;# Params: Offset of string #
;# #
;# #
;# StringLenght - return lenght of string #
;# #
;# #
;####################################################
proc StringLenght ; offset of string(db)
push bp ; Backup
mov bp, sp
push bx ; Finish backup
mov bx, [bp+4] ; Offset of string
StringLenghtUntilDollar:
cmp [byte ptr bx], '$'
je StringLenghtExit ; If [byte ptr bx](char) == dollar, jump to StringLenghtExit
inc bx ; bx++
jmp StringLenghtUntilDollar
StringLenghtExit:
sub bx, [bp+4] ; bx - offset of sting = count
mov [bp+4], bx ; Save count
pop bx ; Restore
pop bp ; Finish restore
ret
endp StringLenght ; Return count
;####################################################
;# #
;# Params: Offset of string #
;# #
;# #
;# AppendCount - Append to count string, 1 #
;# #
;# #
;####################################################
proc AppendCount ; offset of string(db)
push bp ; Backup
mov bp, sp
push bx
push cx ; Finish backup
mov bx, [bp+4] ; offset of string in bx
push [bp+4] ; push offset of string
call StringLenght ; return lenght of string
pop cx ; lenght of string
dec cx ; cx--
add bx, cx ; bx += cx
inc [byte ptr bx] ; [byte ptr bx]++
AppendCountCheck:
cmp [byte ptr bx], 0Ah
jne AppendCountExit ; If [byte ptr bx] != 0Ah, jump to AppendCount Exit
AppendCountResetA:
mov [byte ptr bx], 0 ; Reset [byte ptr bx]([byte ptr bx] = 0)
cmp bx, [bp+4]
je AppendCountExit ; If bx == [bp+4](offset of string), jump to AppendCountExit
inc [byte ptr bx-1] ; [byte ptr bx-1]++
dec bx ; bx--
jmp AppendCountCheck ; If bx > [bp+4](offset of string), jump to AppendCountCheck
AppendCountExit:
pop cx ; Restore
pop bx
pop bp ; Finish restore
ret 2
endp AppendCount
;####################################################
;# #
;# Params: Val(=0) #
;# #
;# #
;# InputKey - Get key from keyboard #
;# #
;# Return - Code ascii of key #
;# #
;####################################################
proc InputKey ; Val(=0)
push bp ; Backup
mov bp, sp
push ax ; Finish backup
mov ah, 7 ; Input key
int 21h
mov [byte ptr bp+4], al ; Save the key in val
pop ax ; Restore
pop bp ; Finish restore
ret
endp InputKey ; Return code ascii of key
;####################################################
;# #
;# Params: Nothing #
;# #
;# #
;# EnableSpeaker - Enable speakers for use #
;# #
;# #
;####################################################
proc EnableSpeaker
push ax ; Backup
in al, SPEAKERS ; Get info form port of speakers
or al, 00000011b ; Enable speakers
out SPEAKERS, al ; Enter to port of speakers
pop ax ; Restore
ret
endp EnableSpeaker
;####################################################
;# #
;# Params: Nothing #
;# #
;# #
;# DisableSpeaker - Disable speakers #
;# #
;# #
;####################################################
proc DisableSpeaker
push ax ; Backup
in al, SPEAKERS ; Get info form port of speakers
and al, 11111100b ; Disable speakers
out SPEAKERS, al ; Enter to port of speakers
pop ax ; Restore
ret
endp DisableSpeaker
;####################################################
;# #
;# Params: Nothing #
;# #
;# #
;# OpenAccessToSpeaker - Open access to speakers #
;# #
;# #
;####################################################
proc OpenAccessToSpeaker
push ax ; Backup
mov al, 0b6h ; Move this value to al
out ACCESS_SPEAKERS, al ; Move the value to port because access to speakers
pop ax ; Restore
ret
endp OpenAccessToSpeaker
;####################################################
;# #
;# Params: Byte of sound #
;# #
;# #
;# PlaySound - play the byte of sound #
;# #
;# #
;####################################################
proc PlaySound ; Byte of sound
push bp ; Backup
mov bp ,sp
push ax ; Finish backup
mov ax, [bp+4] ; Byte of sound
out DIVISOR, al ; Sending lower byte
mov al, ah
out DIVISOR, al ; Sending upper byte
pop ax ; Restore
pop bp ; Finish restore
ret 2
endp PlaySound
;####################################################
;# #
;# Params: Byte of sound #
;# #
;# #
;# Sound - play byte of sound #
;# #
;# #
;####################################################
proc Sound ; num(hz)(dw)
push bp ; Backup
mov bp, sp
call EnableSpeaker
call OpenAccessToSpeaker
push [bp+4] ; Num(Hz)(dw)
call PlaySound
pop bp ; Restore
ret 2
endp Sound
; ############################################## Main ##############################################
start:
mov ax, @data
mov ds, ax
call GraphicMode
HomeScreen: ; Home Screen
push offset PhotoStartArray ; Push offset of home screen photo
call PrintPhotoByArray ; Print home screen photo
HomeScreenInputKey:
push ZERO ; Push 0
call InputKey ; Wait for key from keyboard
pop ax ; pop key to ax
cmp ax, 'p'
je GameScreen ; if key == p, jump to GameScreen
cmp ax, 'P'
je GameScreen ; if key == P, jump to GameScreen
cmp ax, 'i'
je InstructionsScreen ; if ax == 'i'. jump to InstructionsScreen
cmp ax, 'I'
je InstructionsScreen ; if key == I, jump to InstructionsScreen
cmp ax, 'c'
je CreditsScreen ; if key == c, jump to CreditsScreen
cmp ax, 'C'
je CreditsScreen ; if key == C, jump to CreditsScreen
cmp ax, 'E'
je HomeScreenExit ; if key != E, jump to HomeScreenExit
cmp ax, 'e'
jne HomeScreenInputKey ; if key != e, jump to HomeScreenInputKey
HomeScreenExit:
jmp exit ; jump to exit
InstructionsScreen:
push offset PhotoInstructionsArray ; push offset of instructions screen photo
call PrintPhotoByArray ; Print instructions screen photo
InstructionsScreenInputKey:
push ZERO
call InputKey ; wait for input key
pop ax ; key
cmp ax, 'b'
je InstructionsScreenBack ; if ax(key) != 'b', jump to InstructionsScreenBack
cmp ax, 'B'
jne InstructionsScreenInputKey ; if ax(key) != 'B', jump to InstructionsScreenInputKey
InstructionsScreenBack:
jmp HomeScreen
CreditsScreen: ; Credits screen
push offset PhotoCreditsArray ; push offset of credits screen photo
call PrintPhotoByArray ; Print credits screen
CreditsScreenInputKey:
push ZERO ; push 0
call InputKey ; Wait for key from keyboard
pop ax ; pop key
cmp ax, 'b'
je CreditsScreenBack ; if key != b, jump to CreditsScreenBack
cmp ax, 'B'
jne CreditsScreenInputKey ; if key != B, jump to CreditsScreenInputKey
CreditsScreenBack:
jmp HomeScreen ; jump to HomeScreen
GameScreen: ; Game screen
push offset CountApples ; push offset of CountApples
call NumToAscii ; Convert forom num to ascii
push offset ObjectsDisplay ; push offset of ObjectsDisplay
call UpdateDisplay
push SECOND ; 18 * 0.055sec = 1sec
call Delay
call ResetMouse ; Reset mouse
GameIn:
; Check apples -----------------------
push ax ; Backup
push bx
push cx
push si ; Finish backup
mov cx, MANY_APPLES ; Many apples
mov bx, offset Apple1
mov si, offset Bucket
CheckApples:
mov ax, [bx+2] ; move ax, y start
add ax, [bx+6] ; add to ax, y size
cmp ax, Y_START_BUCKET
jne CheckApplesOnGround ; if (ax != 180), jump to CheckApplesOnGround
; Check if apple touch on bucket --------------------------------------------
mov ax, [si] ; move ax x start of bucket
cmp ax, [bx]
ja CheckApplesOnGround ; if x start of bucket > x start of apple, jump to CheckApplesOnGround
add ax, [si+4] ; Add ax x size of bucket
mov si, [bx] ; move x start of apple to si
add si, [bx+4] ; add x size of apple to si
cmp ax, si
jb CheckApplesOnGround ; if x size of bucket < x size of apple, jump to CheckApplesOnGround
push [SoundLe] ; Push sound
call Sound ; Play sound
push ZERO ; minimum for random
push 310 ; maximun for random
call Random ; return random num
pop ax ; random num
mov [bx], ax ; insert the random num to bx(x start)
mov [word ptr bx+2], APPLES_START_Y ; move APPLES_START_Y to the y start of apple
jmp InGameUpdateCount
; Check if apple touch in the ground ----------------------------------
CheckApplesOnGround:
cmp [word ptr bx+2], 190
jb CheckApplesContinue ; if the y start of apple < 190, jump to CheckApplesContinue
; Show Apples in start game ---------------------------------------
cmp [word ptr bx+4], ZERO
jne CheckFailed ; if x size of apple != 0, jump to CheckFailed
mov [word ptr bx+4], APPLE_SIZE ; set x size of apple as 10
mov [word ptr bx+2], APPLES_START_Y ; set y start of apple as APPLES_START_Y
jmp CheckApplesContinue
; Exit to ResetGame -----------------------------------------------
CheckFailed:
push SECOND ; Push 18 for proc Delay(18 * 0.055 sec = 1 sec)
call Delay ; Wait 1 second
jmp TheEndScreen ; jump to TheEndScreen
CheckApplesContinue:
add bx, 10 ; add 10 to bx to move the next apple
loop CheckApples
pop si ; Restore
pop cx
pop bx
pop ax ; Finish restore
; Move mouse -------------------------
push ZERO
push ZERO
call GetLocationMouse ; Return x of mouse, y of mouse
pop ax ; y of mouse
pop ax ; x of mouse
cmp ax, SCREEN_CORNER ; Corner of screen
jb MoveMouseX ; if ax(y) < 270, jump to MoveMouseX
MoveMouseMaximumX:
mov [Bucket], SCREEN_CORNER ; Maximun x for mouse, else the bucket is get out from screen
jmp InGameDelay
MoveMouseX:
mov [Bucket], ax ; move bucket to x location of mouse
InGameDelay:
; Delay -------------------------------
push 1 ; 0.055sec
call Delay ; Delay for 0.055sec
call DisableSpeaker ; Disable Speakers
jmp InGameAppleFall
; Update count -------------------------
InGameUpdateCount: ; Update score
push offset CountApples
call AsciiToNum ; Convert ASCII code to natural numbers
push offset CountApples
call AppendCount ; Append 1 to CountApples
push offset CountApples
call NumToAscii ; Convert natural numbers to ASCII code
jmp CheckApplesContinue
InGameAppleFall:
; Apples fall -------------------------
push cx ; Backup
mov cx, MANY_APPLES ; Many apples
push offset Apple1
push offset Apple2
FallApples:
call MoveObjectDown ; Down apples
loop FallApples
pop cx ; Restore
; Update display -------------------------
InGameUpdateDisplay:
push offset ObjectsDisplay ; push offset of ObjectsDisplay
call UpdateDisplay ; Update display
; ----------------------------------------
jmp GameIn
; -------------------------------------------------------
TheEndScreen: ; The end screen
push cx ; Backup
mov cx, PRINT_NULL_COUNT ; many print null
PrintNull:
push offset StringNull ; push offset of StringNull
call PrintString ; Print StringNull
loop PrintNull
pop cx ; Restore
push offset PhotoEndArray ; Push offset of PhotoEndArray
call PrintPhotoByArray ; Print photo
push offset CountApples ; Push offset of CountApples
call PrintString ; print count apples
; Reset game and objects --------------------------------
ResetGame:
; Apple1 ------------------
mov [Apple1], X_START_APPLE1 ; Reset x start
mov [Apple1+2], APPLES_START_Y+1 ; Reset y start
mov [Apple1+4], ZERO ; Reset x size
; Apple2 ------------------
mov [Apple2], X_START_APPLE2 ; Reset x start
mov [Apple2+2], Y_START_APPLE2+1 ; Reset y start
mov [Apple2+4], ZERO ; Reset x size
; Bucket ------------------
mov [Bucket], X_START_BUCKET ; Reset x start
; Count apples ------------
push bx ; Backup
push cx ; Finish backup
push offset CountApples ; push offset of CountApples
call StringLenght ; Return lenght of string
pop cx ; Lenght of string
lea bx, [CountApples] ; move offset of CountApples to bx
ResetApplesCount:
mov [byte ptr bx], ZERO ; Reset [Byte ptr bx]
inc bx ; bx++
loop ResetApplesCount
pop cx ; Restore
pop bx ; Finish restore
; -------------------------------------------------------
TheEndScreenInputKey:
push ZERO
call InputKey ; Wait for input fron keyboard and return key
pop ax ; key
cmp ax, 'h'
je TheEndScreenBack ; if key != 'h', jump to TheEndScreen
cmp ax, 'H'
jne TheEndScreenInputKey ; if key != 'H', jump to TheEndScreen
call GraphicMode ; Reset screen
TheEndScreenBack:
jmp HomeScreen ; jump to HomeScreen
exit:
call GraphicMode ; Reset screen
mov ax, 4c00h ; Exit from program
int 21h
END start