1320 lines
52 KiB
NASM
1320 lines
52 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 120 ; Light brown color
|
|
; ------------------------------------
|
|
; Ascii ------------------------------
|
|
CARRIAGERET equ 13
|
|
;-------------------------------------
|
|
; Apples settings ----------------------
|
|
MANY_APPLES EQU 3
|
|
APPLES_START_Y equ 4
|
|
SPEED_MOVE equ 7
|
|
X_START_APPLE1 EQU 30
|
|
X_START_APPLE2 EQU 100
|
|
X_START_APPLE3 EQU 150
|
|
Y_START_APPLE2 EQU 64
|
|
Y_START_APPLE3 EQU 124
|
|
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 6
|
|
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,ZERO,APPLE_SIZE,RED
|
|
Apple2 dw X_START_APPLE2,Y_START_APPLE2,ZERO,APPLE_SIZE,RED
|
|
Apple3 dw X_START_APPLE3,Y_START_APPLE3,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 Apple1,offset Apple2,offset Apple3,offset Bucket,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 #
|
|
;# #
|
|
;# #
|
|
;# Print_rect - Draws a rectangle #
|
|
;# #
|
|
;# #
|
|
;############################################
|
|
proc Print_rect ; 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 Print_rectExit ; If dx(x size) == 0, jump to Print_rectExit
|
|
mov cx, [si+6] ; y size
|
|
cmp cx, ZERO
|
|
je Print_rectExit ; If cx(y size) == 0, jump to Print_rectExit
|
|
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
|
|
Print_rectExit:
|
|
pop di ; Restore
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
pop bp ; Finish Restore
|
|
ret 2
|
|
endp Print_rect
|
|
|
|
|
|
;############################################
|
|
;# #
|
|
;# 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 + 7
|
|
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 Print_rect ; 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 #
|
|
;# #
|
|
;# #
|
|
;############################################
|
|
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) #
|
|
;# #
|
|
;############################################
|
|
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 #
|
|
;# #
|
|
;####################################################################
|
|
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
|
|
je RandomNotMul
|
|
mul bx ; mul with ax
|
|
jmp RandomMulContinue
|
|
RandomNotMul:
|
|
mov bx, 23
|
|
mul 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 #
|
|
;# #
|
|
;####################################################
|
|
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 #
|
|
;# #
|
|
;# #
|
|
;####################################################
|
|
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 interrup
|
|
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 #
|
|
;# #
|
|
;# #
|
|
;# HideMouse - Hide 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) #
|
|
;# #
|
|
;# #
|
|
;####################################################
|
|
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, 'i'
|
|
je InstructionsScreen ; if ax == 'i'. jump to InstructionsScreen
|
|
cmp ax, 'c'
|
|
je CreditsScreen ; if key == c, jump to CreditsScreen
|
|
cmp ax, 'e'
|
|
jne HomeScreenInputKey ; if key != e, jump to HomeScreenInputKey
|
|
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'
|
|
jne InstructionsScreenInputKey ; if ax(key) != 'b', jump to InstructionsScreenInputKey
|
|
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'
|
|
jne CreditsScreenInputKey ; if key != b, jump to CreditsScreenInputKey
|
|
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:
|
|
; Apples fall -------------------------
|
|
push cx ; Backup
|
|
mov cx, MANY_APPLES ; Many apples
|
|
push offset Apple1
|
|
push offset Apple2
|
|
push offset Apple3
|
|
FallApples:
|
|
call MoveObjectDown
|
|
loop FallApples
|
|
pop cx ; Restore
|
|
; 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, 182
|
|
jne CheckApplesOnGround ; if !(ax >= 182), 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], 10 ; 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, y
|
|
pop ax ; y
|
|
pop ax ; x
|
|
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 InGameUpdateDisplay
|
|
; Update count -------------------------
|
|
InGameUpdateCount: ; Update score
|
|
push offset CountApples
|
|
call AsciiToNum
|
|
push offset CountApples
|
|
call AppendCount
|
|
push offset CountApples
|
|
call NumToAscii
|
|
jmp CheckApplesContinue
|
|
; Update display -------------------------
|
|
InGameUpdateDisplay:
|
|
push offset ObjectsDisplay ; push offset of ObjectsDisplay
|
|
call UpdateDisplay
|
|
; -------------------------
|
|
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
|
|
mov [Apple1+2], APPLES_START_Y
|
|
mov [Apple1+4], ZERO
|
|
; Apple2 ------------------
|
|
mov [Apple2], X_START_APPLE2
|
|
mov [Apple2+2], Y_START_APPLE2
|
|
mov [Apple2+4], ZERO
|
|
; Apple3 ------------------
|
|
mov [Apple3], X_START_APPLE3
|
|
mov [Apple3+2], Y_START_APPLE3
|
|
mov [Apple3+4], ZERO
|
|
; Bucket ------------------
|
|
mov [Bucket], X_START_BUCKET
|
|
; 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, 'e'
|
|
je exit ; if key == 'e', jump to exit
|
|
cmp ax, 'h'
|
|
jne TheEndScreenInputKey ; if key != 'h', jump to TheEndScreen
|
|
call GraphicMode ; Reset screen
|
|
jmp HomeScreen ; jump to HomeScreen
|
|
|
|
|
|
exit:
|
|
call GraphicMode ; Reset screen
|
|
mov ax, 4c00h
|
|
int 21h
|
|
END start |