├── ChooseColorPROC.asm ├── Fibonacci.asm ├── HollowSquare.asm ├── SwitchElements.asm ├── RandomXs.asm ├── AddArrayElements.asm ├── RandomNumFiller.asm ├── Calculator.asm ├── Grades.asm ├── SievePrimes.asm ├── Assembly-2D-Platformer └── Assembly-Snake.asm /ChooseColorPROC.asm: -------------------------------------------------------------------------------- 1 | ChooseColor PROC 2 | mov eax, 11 ; generate random (0-10) 3 | call RandomRange ; EAX = random value 4 | 5 | L_Green: ; if N = 8-10, choose green 6 | cmp eax,8 7 | jb L_Cyan 8 | mov eax,green 9 | jmp L_Finished 10 | 11 | L_Cyan: ; if N = 5-7, choose cyan 12 | cmp eax,5 13 | jb L_Magenta 14 | mov eax,cyan 15 | jmp L_Finished 16 | 17 | L_Magenta: 18 | cmp eax,3 19 | jb L_White 20 | mov eax,lightMagenta 21 | jmp L_Finished 22 | 23 | L_White: ; if N = 0-2, choose white 24 | mov eax,white 25 | 26 | L_Finished: 27 | ret 28 | 29 | ChooseColor ENDP -------------------------------------------------------------------------------- /Fibonacci.asm: -------------------------------------------------------------------------------- 1 | ; The Fibonacci Sequence by Ben Bollinger 2 | 3 | include Irvine32.inc 4 | 5 | .data 6 | 7 | num1 DWORD 1 8 | num2 DWORD 1 9 | 10 | .code 11 | main PROC 12 | 13 | ; print first two nums: 14 | mov eax,0 15 | mov eax,num1 16 | call WriteInt 17 | call Crlf 18 | mov eax,num2 19 | call WriteInt 20 | call Crlf 21 | 22 | ; print the next 20: 23 | mov ecx,20 24 | L1: 25 | ; add num1 and num2: 26 | mov eax,num1 27 | add eax,num2 28 | call WriteInt 29 | call Crlf 30 | 31 | ; set num1 to the value of num2: 32 | mov edx,num2 33 | mov num1,edx 34 | 35 | ; set num2 to the previous (num1+num2): 36 | mov num2,eax 37 | loop L1 38 | 39 | exit 40 | main ENDP 41 | 42 | END main 43 | -------------------------------------------------------------------------------- /HollowSquare.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | include Irvine32.inc 4 | 5 | .data 6 | rows = 10 7 | cols = 10 8 | 9 | .code 10 | main PROC 11 | 12 | mov ecx,rows 13 | outterLoop: 14 | mov al,'*' 15 | call WriteChar 16 | 17 | mov edx,ecx 18 | push ecx 19 | mov ecx,cols 20 | innerLoop: 21 | cmp edx,cols 22 | je drawFirst 23 | jne checkSecond 24 | 25 | drawFirst: 26 | mov al,'*' 27 | call WriteChar 28 | jmp continueLoop 29 | 30 | checkSecond: 31 | cmp edx,1 32 | je drawSecond 33 | jne drawSide 34 | 35 | drawSecond: 36 | mov al,'*' 37 | call WriteChar 38 | jmp continueLoop 39 | 40 | drawSide: 41 | cmp ecx,1 42 | je drawEnd 43 | jne drawSpace 44 | 45 | drawEnd: 46 | mov al,'*' 47 | call WriteChar 48 | jmp continueLoop 49 | 50 | drawSpace: 51 | mov al,' ' 52 | call WriteChar 53 | 54 | continueLoop: 55 | loop innerLoop 56 | pop ecx 57 | 58 | call Crlf 59 | loop outterLoop 60 | 61 | exit 62 | main ENDP 63 | END main -------------------------------------------------------------------------------- /SwitchElements.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | numList BYTE 1,2,3,4,5,6,7,8,9 8 | ArraySize = ($ - numList) 9 | sizeMinus DWORD ? 10 | 11 | .code 12 | main PROC 13 | ; get size-1 14 | mov ecx,ArraySize 15 | dec ecx 16 | mov sizeMinus,ecx 17 | 18 | ; set init index to 0: 19 | mov ecx,0 20 | L1: 21 | ; check if end of loop: 22 | cmp ecx,sizeMinus 23 | je exitL1 24 | 25 | ; get current iteration plus one in ebx: 26 | mov ebx,ecx 27 | inc ebx 28 | 29 | ; make the switch: 30 | mov dl,[numList+ebx] 31 | mov dh,[numList+ecx] 32 | 33 | mov [numList+ebx],dh 34 | mov [numList+ecx],dl 35 | 36 | inc ecx 37 | jmp L1 38 | 39 | exitL1: 40 | 41 | ; display new array: 42 | mov eax,0 43 | mov ecx,0 44 | L2: 45 | ; check if end of loop: 46 | cmp ecx,ArraySize 47 | je quit 48 | 49 | ; display current iteration: 50 | mov al,[numList+ecx] 51 | call WriteInt 52 | inc ecx 53 | jmp L2 54 | 55 | quit: 56 | exit 57 | main ENDP 58 | END main -------------------------------------------------------------------------------- /RandomXs.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | str1 BYTE "X",0 8 | 9 | yPos BYTE ? 10 | xPos BYTE ? 11 | 12 | coordListX BYTE 50 DUP(?) 13 | coordListY BYTE 50 DUP(?) 14 | 15 | .code 16 | main PROC 17 | 18 | ; loop 50 times 19 | mov ecx,50 20 | 21 | call Randomize 22 | ; draw x loop: 23 | L1: 24 | ; generate random row position: 25 | mov eax,10 26 | call RandomRange 27 | mov yPos,al 28 | 29 | ; log yPos: 30 | mov [coordListX+ecx],al 31 | 32 | ; clear eax: 33 | mov eax,0 34 | 35 | ; generate random col position: 36 | mov eax,100 37 | call RandomRange 38 | mov xPos,al 39 | 40 | ; log xPos: 41 | mov [coordListY+ecx],al 42 | 43 | ; draw the X: 44 | call DrawX 45 | 46 | loop L1 47 | exit 48 | main ENDP 49 | 50 | ; input an integer 51 | DrawX PROC 52 | call Locate 53 | mov edx,OFFSET str1 54 | call WriteString 55 | ret 56 | DrawX ENDP 57 | 58 | ; locate the cursor 59 | Locate PROC 60 | mov dh,yPos 61 | mov dl,xPos 62 | call Gotoxy 63 | ret 64 | Locate ENDP 65 | 66 | END main -------------------------------------------------------------------------------- /AddArrayElements.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | str1 BYTE "Enter an integer: " 8 | row BYTE ? 9 | col BYTE ? 10 | 11 | myArray DWORD 4 DUP(?) 12 | ArraySize = ($-myArray) ; get size of array 13 | 14 | .code 15 | main PROC 16 | mov ecx,0 ; reset ecx 17 | 18 | ; get array values loop: 19 | L1: 20 | ; loop the size of the array: 21 | cmp ecx,ArraySize 22 | jge END1 23 | 24 | ; input values: 25 | call Input 26 | add [myArray+ecx],eax 27 | add row,1 28 | 29 | add ecx,4 30 | jmp L1 31 | END1: 32 | 33 | mov ebx,0 ; set ebx to 0 34 | mov ecx,0 ; set ecx to 0 35 | 36 | L2: 37 | cmp ecx,ArraySize ; check if counter is greater than size of array 38 | jge END2 ; if it's greater, then end the loop 39 | 40 | add ebx,[myArray+ecx] ; add current array index to eax 41 | mov eax,ebx ; move new value to display register 42 | call WriteInt ; display current value 43 | 44 | add ecx,4 ; increment counter by 4 (bytes) 45 | jmp L2 ; restart loop 46 | END2: 47 | 48 | exit 49 | main ENDP 50 | 51 | ; input an integer 52 | Input PROC 53 | call Locate 54 | mov edx,OFFSET str1 55 | call WriteString 56 | mov edx,0 57 | call ReadInt 58 | ret 59 | Input ENDP 60 | 61 | ; locate the cursor 62 | Locate PROC 63 | mov dh,row 64 | mov dl,col 65 | call Gotoxy 66 | ret 67 | Locate ENDP 68 | 69 | END main -------------------------------------------------------------------------------- /RandomNumFiller.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | row BYTE ? 8 | col BYTE ? 9 | 10 | rows = 30 11 | cols = 30 12 | numOfElements = (rows * cols) 13 | 14 | coordList DWORD numOfElements DUP(0) 15 | coordPos DWORD ? 16 | 17 | .code 18 | main PROC 19 | 20 | ; loop x times 21 | mov ecx,7000 22 | 23 | call Randomize 24 | ; draw x loop: 25 | L1: 26 | call RandomCoords 27 | 28 | ; get coord position ((row-1) * cols) + col: 29 | dec row 30 | mov al,row 31 | push ecx 32 | mov ecx,cols 33 | mul ecx 34 | pop ecx 35 | add al,col 36 | 37 | ; fix to a weird bug: 38 | cmp eax,numOfElements 39 | jae weirdBug 40 | 41 | ; increment value at position: 42 | inc [coordList+eax] 43 | mov coordPos,eax 44 | mov eax,[coordList+eax] 45 | add al,'0' 46 | 47 | ; if number > 9 then reset to 0: 48 | cmp al,'9' 49 | jl lessNine 50 | mov edx,coordPos 51 | mov [coordList+edx],0 52 | mov eax,[coordList+edx] 53 | add al,'0' 54 | 55 | ; if number < 9, just draw it as is: 56 | lessNine: 57 | call DrawNum 58 | 59 | mov eax,1 60 | call Delay 61 | 62 | weirdBug: 63 | loop L1 64 | 65 | call ReadChar 66 | exit 67 | main ENDP 68 | 69 | ; write the number: 70 | DrawNum PROC 71 | call Locate 72 | push eax 73 | call ChooseColor 74 | pop eax 75 | call WriteChar 76 | ret 77 | DrawNum ENDP 78 | 79 | ; position the cursor 80 | Locate PROC 81 | mov dh,row 82 | mov dl,col 83 | call Gotoxy 84 | ret 85 | Locate ENDP 86 | 87 | RandomCoords PROC 88 | ; generate random row position: 89 | mov eax,rows 90 | call RandomRange 91 | mov row,al 92 | 93 | ; generate random col position: 94 | mov eax,cols 95 | call RandomRange 96 | mov col,al 97 | RandomCoords ENDP 98 | 99 | ChooseColor PROC 100 | ; generate random forecolor: 101 | mov eax,15 102 | call RandomRange 103 | inc eax 104 | call SetTextColor 105 | ret 106 | ChooseColor ENDP 107 | 108 | END main -------------------------------------------------------------------------------- /Calculator.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | str1 BYTE "Enter an integer: ",0 8 | str2 BYTE "Enter an operator: ",0 9 | 10 | PLUS = '+' 11 | MINUS = '-' 12 | MULT = '*' 13 | DIVIDE = '/' 14 | 15 | operator BYTE ? 16 | num1 DWORD ? 17 | num2 DWORD ? 18 | 19 | row BYTE ? 20 | col BYTE ? 21 | 22 | .code 23 | main PROC 24 | ; get numbers: 25 | call InputInt 26 | mov num1,eax 27 | mov ebx,num1 ; put num1 in ebx 28 | 29 | add row,2 30 | 31 | call InputInt 32 | mov num2,eax 33 | 34 | add row,2 35 | 36 | ; get the operator: 37 | call InputOperator 38 | mov operator,al 39 | 40 | add row,2 41 | 42 | ; if + 43 | checkPlus: 44 | cmp operator,PLUS 45 | jne checkMinus 46 | 47 | add ebx,num2 48 | mov eax,ebx 49 | call WriteInt 50 | 51 | ; if - 52 | checkMinus: 53 | cmp operator,MINUS 54 | jne checkMult 55 | 56 | sub ebx,num2 57 | mov eax,ebx 58 | call WriteInt 59 | 60 | ; if * 61 | checkMult: 62 | cmp operator,MULT 63 | jne checkDiv 64 | 65 | mov edx,0 ; clear dividend 66 | mov eax,num1 ; first num 67 | mov ecx,num2 ; second num 68 | mul ecx ; multiply 69 | 70 | call WriteInt ; result already written to eax 71 | 72 | ; if / 73 | checkDiv: 74 | cmp operator,DIVIDE 75 | 76 | mov edx,0 ; clear dividend 77 | mov eax,num1 ; dividend 78 | mov ecx,num2 ; divisor 79 | div ecx ; divide 80 | 81 | call WriteInt ; result already written to eax 82 | 83 | jne quit 84 | 85 | quit: 86 | exit 87 | main ENDP 88 | 89 | ; input an integer 90 | InputInt PROC 91 | call Locate 92 | mov edx,OFFSET str1 93 | call WriteString 94 | call ReadInt 95 | ret 96 | InputInt ENDP 97 | 98 | ; input an operator 99 | InputOperator PROC 100 | call Locate 101 | mov edx,OFFSET str2 102 | call WriteString 103 | call ReadChar 104 | ret 105 | InputOperator ENDP 106 | 107 | ; locate the cursor 108 | Locate PROC 109 | mov dh,row 110 | mov dl,col 111 | call Gotoxy 112 | ret 113 | Locate ENDP 114 | 115 | END main -------------------------------------------------------------------------------- /Grades.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | include Irvine32.inc 4 | 5 | .data 6 | str1 BYTE ": The letter grade is ",0 7 | grade BYTE ? 8 | 9 | .code 10 | main PROC 11 | call Randomize 12 | 13 | mov ecx,10 ; repeat loop 10 times 14 | again: 15 | ; Save loop counter 16 | push ecx 17 | ; Generate a random number between 50 and 100. 18 | ; If you move 51 to eax before calling RandomRange, 19 | ; you will generate a random number between 0 and 50. 20 | ; Add 50 to eax to generate a number between 50 and 100. 21 | ; Use WriteDec to output the random number that will be used to calculate a letter grade. 22 | ; INSERT CODE HERE--> 23 | mov eax,51 24 | call RandomRange 25 | add eax,50 26 | call WriteDec 27 | 28 | call CalcGrade ; returns the grade in AL 29 | ; Save the grade returned from CalcGrade as grade. 30 | ; Use WriteString to display the value of str1. 31 | ; You will need to move the OFFSET of str1 to edx before calling WriteString. 32 | ; Return the grade back to the al register and display it by calling WriteChar. 33 | ; Generate a carriage control line feed. 34 | ; INSERT CODE HERE--> 35 | mov edx,OFFSET str1 36 | call WriteString 37 | call WriteChar 38 | call Crlf 39 | 40 | ; Restore the loop counter. 41 | pop ecx 42 | ; INSERT CODE HERE--> 43 | loop again 44 | 45 | exit 46 | main ENDP 47 | 48 | CalcGrade PROC 49 | ; Calculates a letter grade 50 | ; Receives: EAX = numeric grade 51 | ; Returns: AL = letter grade 52 | 53 | Grade_A: 54 | ; The eax register contains the numeric grade. 55 | ; Add code to compare eax against 90 and jump to Grade_B if eax is less than 90. 56 | ; If eax is not less than 90, move an A to al and jump to finished. 57 | ; INSERT CODE HERE--> 58 | cmp eax,90 59 | jl Grade_B 60 | mov al,'A' 61 | jmp finished 62 | 63 | Grade_B: 64 | ; INSERT CODE HERE to test for a B. 65 | cmp eax,80 66 | jl Grade_C 67 | mov al,'B' 68 | jmp finished 69 | 70 | Grade_C: 71 | ; INSERT CODE HERE to test for a C. 72 | cmp eax,70 73 | jl Grade_D 74 | mov al,'C' 75 | jmp finished 76 | 77 | Grade_D: 78 | ; INSERT CODE HERE to test for a D. 79 | cmp eax,60 80 | jl Grade_F 81 | mov al,'D' 82 | jmp finished 83 | 84 | Grade_F: 85 | ; INSERT CODE HERE for a default grade of F. 86 | mov al,'F' 87 | 88 | finished: 89 | ret 90 | CalcGrade ENDP 91 | 92 | END main -------------------------------------------------------------------------------- /SievePrimes.asm: -------------------------------------------------------------------------------- 1 | ; Chapter 7 Exercise 5: Prime Numbers 2 | 3 | ;Comment ! 4 | ;Write a program that generates all prime numbers between 2 and 1000, 5 | ;using the Sieve of Eratosthenes method. You can find many articles that 6 | ;describe the method for finding primes in this manner on the Internet. 7 | ;Display all the prime values. 8 | ;! 9 | 10 | INCLUDE Irvine32.inc 11 | 12 | PrintPrimes PROTO, 13 | count:DWORD ; number of values to display 14 | 15 | FIRST_PRIME = 2 16 | LAST_PRIME = 20 ; try a larger array than 65,000 17 | 18 | .data 19 | commaStr BYTE ", ",0 20 | 21 | .data? 22 | sieve BYTE LAST_PRIME DUP(?) 23 | 24 | .code 25 | main PROC 26 | ; initialize the array to zeros 27 | mov ecx,LAST_PRIME ; set ecx to LAST_PRIME 28 | mov edi,OFFSET sieve ; set edi to the first element in sieve array 29 | 30 | ; sets direction flag to zero so edi and esi are incremented: 31 | mov al,0 32 | cld 33 | rep stosb 34 | 35 | mov esi,FIRST_PRIME 36 | 37 | ; loop through all primes from FIRST_PRIME to LAST_PRIME: 38 | .WHILE esi < LAST_PRIME 39 | ; if the current iteration (esi) equals zero then it's a prime number (if marked then 1, if not then 0): 40 | .IF sieve[esi*TYPE sieve] == 0 41 | call MarkMultiples 42 | .ENDIF 43 | inc esi 44 | .ENDW 45 | 46 | INVOKE PrintPrimes, LAST_PRIME 47 | 48 | exit 49 | main ENDP 50 | 51 | ;-------------------------------------------------- 52 | MarkMultiples PROC 53 | ; 54 | ; Mark all multiples of the value passed in ESI. 55 | ; Notice we use ESI as the prime value, and 56 | ; take advantage of the "scaling" feature of indirect 57 | ; operands to locate the address of the indexed item: 58 | ; [esi*TYPE sieve] 59 | ;-------------------------------------------------- 60 | 61 | ; double the value of the current iteration and save the registers, determines first multiple: 62 | push eax 63 | push esi 64 | mov eax,esi 65 | add esi,eax 66 | 67 | ; gets the multiples of the prime numbers and marks them as 1: 68 | L1: cmp esi,LAST_PRIME 69 | ja L2 70 | mov sieve[esi*TYPE sieve],1 71 | add esi,eax 72 | jmp L1 73 | 74 | ; exit the procedure and restore registers: 75 | L2: pop esi 76 | pop eax 77 | ret 78 | MarkMultiples ENDP 79 | 80 | 81 | ;-------------------------------------------------- 82 | PrintPrimes PROC, 83 | count:DWORD ; number of values to display 84 | ; 85 | ; Display the list of prime numbers 86 | ;-------------------------------------------------- 87 | mov esi,1 88 | mov eax,0 89 | mov ecx,count ; value of last prime 90 | 91 | ; putting the second element of sieve into al 92 | L1: mov al,sieve[esi*TYPE sieve] 93 | ; if current iter has been marked as 0, the it's prime: 94 | .IF al == 0 95 | ; then write it to the screen: 96 | mov eax,esi 97 | call WriteDec 98 | mov edx,OFFSET commaStr 99 | call WriteString 100 | .ENDIF 101 | inc esi 102 | ; keep looping until LAST_PRIME: 103 | loop L1 104 | 105 | ret 106 | PrintPrimes ENDP 107 | 108 | 109 | END main 110 | -------------------------------------------------------------------------------- /Assembly-2D-Platformer: -------------------------------------------------------------------------------- 1 | INCLUDE Irvine32.inc 2 | 3 | .data 4 | 5 | ground BYTE "------------------------------------------------------------------------------------------------------------------------",0 6 | 7 | strScore BYTE "Your score is: ",0 8 | score BYTE 0 9 | 10 | xPos BYTE 20 11 | yPos BYTE 20 12 | 13 | xCoinPos BYTE ? 14 | yCoinPos BYTE ? 15 | 16 | inputChar BYTE ? 17 | 18 | .code 19 | main PROC 20 | ; draw ground at (0,29): 21 | mov dl,0 22 | mov dh,29 23 | call Gotoxy 24 | mov edx,OFFSET ground 25 | call WriteString 26 | 27 | call DrawPlayer 28 | 29 | call CreateRandomCoin 30 | call DrawCoin 31 | 32 | call Randomize 33 | 34 | gameLoop: 35 | 36 | ; getting points: 37 | mov bl,xPos 38 | cmp bl,xCoinPos 39 | jne notCollecting 40 | mov bl,yPos 41 | cmp bl,yCoinPos 42 | jne notCollecting 43 | ; player is intersecting coin: 44 | inc score 45 | call CreateRandomCoin 46 | call DrawCoin 47 | notCollecting: 48 | 49 | mov eax,white (black * 16) 50 | call SetTextColor 51 | 52 | ; draw score: 53 | mov dl,0 54 | mov dh,0 55 | call Gotoxy 56 | mov edx,OFFSET strScore 57 | call WriteString 58 | mov al,score 59 | call WriteInt 60 | 61 | ; gravity logic: 62 | gravity: 63 | cmp yPos,27 64 | jg onGround 65 | ; make player fall: 66 | call UpdatePlayer 67 | inc yPos 68 | call DrawPlayer 69 | mov eax,80 70 | call Delay 71 | jmp gravity 72 | onGround: 73 | 74 | ; get user key input: 75 | call ReadChar 76 | mov inputChar,al 77 | 78 | ; exit game if user types 'x': 79 | cmp inputChar,"x" 80 | je exitGame 81 | 82 | cmp inputChar,"w" 83 | je moveUp 84 | 85 | cmp inputChar,"s" 86 | je moveDown 87 | 88 | cmp inputChar,"a" 89 | je moveLeft 90 | 91 | cmp inputChar,"d" 92 | je moveRight 93 | 94 | moveUp: 95 | ; allow player to jump: 96 | mov ecx,1 97 | jumpLoop: 98 | call UpdatePlayer 99 | dec yPos 100 | call DrawPlayer 101 | mov eax,70 102 | call Delay 103 | loop jumpLoop 104 | jmp gameLoop 105 | 106 | moveDown: 107 | call UpdatePlayer 108 | inc yPos 109 | call DrawPlayer 110 | jmp gameLoop 111 | 112 | moveLeft: 113 | call UpdatePlayer 114 | dec xPos 115 | call DrawPlayer 116 | jmp gameLoop 117 | 118 | moveRight: 119 | call UpdatePlayer 120 | inc xPos 121 | call DrawPlayer 122 | jmp gameLoop 123 | 124 | jmp gameLoop 125 | 126 | exitGame: 127 | exit 128 | main ENDP 129 | 130 | DrawPlayer PROC 131 | ; draw player at (xPos,yPos): 132 | mov dl,xPos 133 | mov dh,yPos 134 | call Gotoxy 135 | mov al,"X" 136 | call WriteChar 137 | ret 138 | DrawPlayer ENDP 139 | 140 | UpdatePlayer PROC 141 | mov dl,xPos 142 | mov dh,yPos 143 | call Gotoxy 144 | mov al," " 145 | call WriteChar 146 | ret 147 | UpdatePlayer ENDP 148 | 149 | DrawCoin PROC 150 | mov eax,yellow (yellow * 16) 151 | call SetTextColor 152 | mov dl,xCoinPos 153 | mov dh,yCoinPos 154 | call Gotoxy 155 | mov al,"X" 156 | call WriteChar 157 | ret 158 | DrawCoin ENDP 159 | 160 | CreateRandomCoin PROC 161 | mov eax,55 162 | inc eax 163 | call RandomRange 164 | mov xCoinPos,al 165 | mov yCoinPos,27 166 | ret 167 | CreateRandomCoin ENDP 168 | 169 | END main 170 | -------------------------------------------------------------------------------- /Assembly-Snake.asm: -------------------------------------------------------------------------------- 1 | ; by Ben Bollinger 2 | 3 | INCLUDE Irvine32.inc 4 | 5 | .data 6 | 7 | strWelcome BYTE "Welcome to an x86 Assembly Game by Ben Bollinger (WASD to move, x to exit)",0 8 | strLine BYTE "--------------------------------------------------------------------------",0 9 | 10 | inputChar BYTE ? 11 | 12 | xPos BYTE ? 13 | yPos BYTE ? 14 | 15 | xApplePos BYTE ? 16 | yApplePos BYTE ? 17 | 18 | isColliding BYTE 'F' 19 | right BYTE 'F' 20 | left BYTE 'F' 21 | up BYTE 'F' 22 | down BYTE 'F' 23 | 24 | applesEaten DWORD 0 25 | adder DWORD 2 26 | 27 | .code 28 | main PROC 29 | ; display welcome message: 30 | mov dl,1 31 | mov dh,0 32 | call Gotoxy 33 | mov edx,OFFSET strWelcome 34 | call WriteString 35 | mov dl,1 36 | mov dh,1 37 | call Gotoxy 38 | mov edx,0 39 | mov edx,OFFSET strLine 40 | call WriteString 41 | 42 | call DrawRandomApple 43 | 44 | ; set init player position: 45 | mov xPos,10 46 | mov yPos,10 47 | 48 | call ReadChar 49 | mov inputChar,al 50 | 51 | ; start game loop: 52 | gameLoop: 53 | call DrawAppleCont 54 | ; delay for 80ms 55 | mov eax,40 56 | call Delay 57 | 58 | ; read keybuffer into al: 59 | call ReadKey 60 | 61 | ;------------------------------------------------------------------------------ 62 | ; make sure keybuffer only goes to inputChar if it's one of the specified keys: 63 | cmp al,"w" 64 | jne checkS 65 | mov inputChar,al 66 | 67 | checkS: 68 | cmp al,"s" 69 | jne checkA 70 | mov inputChar,al 71 | 72 | checkA: 73 | cmp al,"a" 74 | jne checkD 75 | mov inputChar,al 76 | 77 | checkD: 78 | cmp al,"d" 79 | jne skip 80 | mov inputChar,al 81 | 82 | skip: 83 | ;------------------------------------------------------------------------------ 84 | 85 | ; check for game exit: 86 | cmp inputChar,"x" 87 | je exitGame 88 | 89 | ; check for 'w' (up): 90 | cmp inputChar,"w" 91 | je moveUp 92 | 93 | ; check for 's' (down): 94 | cmp inputChar,"s" 95 | je moveDown 96 | 97 | ; check for 'd' (right): 98 | cmp inputChar,"d" 99 | je moveRight 100 | 101 | ; check for 'a' (left): 102 | cmp inputChar,"a" 103 | je moveLeft 104 | jmp gameLoop 105 | 106 | ; move the player up: 107 | moveUp: 108 | ; clear current player location: 109 | call RefreshPlayer 110 | 111 | ; decrement yPos (move up) and draw Player: 112 | dec yPos 113 | call DrawPlayer 114 | 115 | ; check apple collisions: 116 | call CheckAppleCollision 117 | cmp isColliding,'T' 118 | jne noCollide1 119 | ; if collision happened: 120 | inc applesEaten 121 | call DrawRandomApple 122 | noCollide1: 123 | 124 | mov right,'F' 125 | mov left,'F' 126 | mov down,'F' 127 | mov up,'T' 128 | 129 | ; reset input and repeat loop: 130 | jmp gameLoop 131 | 132 | ; move the player down: 133 | moveDown: 134 | ; clear current player location: 135 | call RefreshPlayer 136 | 137 | ; increment yPos (move down) and draw Player: 138 | inc yPos 139 | call DrawPlayer 140 | 141 | ; check apple collisions: 142 | call CheckAppleCollision 143 | cmp isColliding,'T' 144 | jne noCollide2 145 | ; if collision happened: 146 | inc applesEaten 147 | call DrawRandomApple 148 | noCollide2: 149 | 150 | mov right,'F' 151 | mov left,'F' 152 | mov down,'T' 153 | mov up,'F' 154 | 155 | ; reset input and repeat loop: 156 | jmp gameLoop 157 | 158 | ; move the player right: 159 | moveRight: 160 | ; clear current player location: 161 | call RefreshPlayer 162 | 163 | ; increment yPos (move down) and draw Player: 164 | inc xPos 165 | call DrawPlayer 166 | 167 | ; check apple collisions: 168 | call CheckAppleCollision 169 | cmp isColliding,'T' 170 | jne noCollide3 171 | ; if collision happened: 172 | inc applesEaten 173 | call DrawRandomApple 174 | noCollide3: 175 | 176 | mov right,'T' 177 | mov left,'F' 178 | mov down,'F' 179 | mov up,'F' 180 | 181 | ; reset input and repeat loop: 182 | jmp gameLoop 183 | 184 | ; move the player left: 185 | moveLeft: 186 | ; clear current player location: 187 | call RefreshPlayer 188 | 189 | ; increment yPos (move down) and draw Player: 190 | dec xPos 191 | call DrawPlayer 192 | 193 | ; check apple collisions: 194 | call CheckAppleCollision 195 | cmp isColliding,'T' 196 | jne noCollide4 197 | ; if collision happened: 198 | inc applesEaten 199 | call DrawRandomApple 200 | noCollide4: 201 | 202 | mov right,'F' 203 | mov left,'T' 204 | mov down,'F' 205 | mov up,'F' 206 | 207 | ; reset input and repeat loop: 208 | jmp gameLoop 209 | 210 | jmp gameLoop 211 | 212 | exitGame: 213 | exit 214 | main ENDP 215 | 216 | ; clear current player so to draw at new location: 217 | RefreshPlayer PROC 218 | ; get the previous location of the player: 219 | mov dl,xPos 220 | mov dh,yPos 221 | 222 | ; as the player eats more apples, cover up less spots behind him: 223 | cmp applesEaten,0 224 | je noApples 225 | mov ecx,applesEaten 226 | playerLoop: 227 | cmp right,'T' 228 | jne goingLeft 229 | dec dl 230 | 231 | goingLeft: 232 | cmp left,'T' 233 | jne goingUp 234 | inc dl 235 | 236 | goingUp: 237 | cmp up,'T' 238 | jne goingDown 239 | inc dh 240 | 241 | goingDown: 242 | cmp down,'T' 243 | jne finishLoop 244 | dec dh 245 | 246 | finishLoop: 247 | loop playerLoop 248 | 249 | call DeletePlayerPixels 250 | 251 | cmp up,'T' 252 | jne checkDown 253 | call GetAdder 254 | ; as the body expands, the area of deletion expands proportionally: 255 | push ecx 256 | add esi,edi 257 | mov ecx,esi 258 | upLoop1: 259 | dec dl 260 | call DeletePlayerPixels 261 | loop upLoop1 262 | pop ecx 263 | 264 | push ecx 265 | inc edi 266 | add esi,edi 267 | mov ecx,esi 268 | upLoop2: 269 | inc dl 270 | call DeletePlayerPixels 271 | loop upLoop2 272 | pop ecx 273 | checkDown: 274 | cmp down,'T' 275 | jne checkRight 276 | push ecx 277 | add applesEaten,2 278 | mov ecx,applesEaten 279 | downLoop1: 280 | inc dl 281 | call DeletePlayerPixels 282 | loop downLoop1 283 | pop ecx 284 | 285 | push ecx 286 | add applesEaten,3 287 | mov ecx,applesEaten 288 | downLoop2: 289 | dec dl 290 | call DeletePlayerPixels 291 | loop downLoop2 292 | pop ecx 293 | sub applesEaten,5 294 | checkRight: 295 | cmp right,'T' 296 | jne checkLeft 297 | push ecx 298 | add applesEaten,2 299 | mov ecx,applesEaten 300 | rightLoop1: 301 | dec dh 302 | call DeletePlayerPixels 303 | loop rightLoop1 304 | pop ecx 305 | 306 | push ecx 307 | add applesEaten,3 308 | mov ecx,applesEaten 309 | rightLoop2: 310 | inc dh 311 | call DeletePlayerPixels 312 | loop rightLoop2 313 | pop ecx 314 | sub applesEaten,5 315 | checkLeft: 316 | cmp left,'T' 317 | jne noApples 318 | push ecx 319 | add applesEaten,2 320 | mov ecx,applesEaten 321 | leftLoop1: 322 | inc dh 323 | call DeletePlayerPixels 324 | loop leftLoop1 325 | pop ecx 326 | 327 | push ecx 328 | add applesEaten,3 329 | mov ecx,applesEaten 330 | leftLoop2: 331 | dec dh 332 | call DeletePlayerPixels 333 | loop leftLoop2 334 | pop ecx 335 | sub applesEaten,5 336 | noApples: 337 | RefreshPlayer ENDP 338 | 339 | GetAdder PROC 340 | mov esi,applesEaten 341 | add esi,adder 342 | mov edi,esi 343 | mov esi,applesEaten 344 | GetAdder ENDP 345 | 346 | DeletePlayerPixels PROC 347 | call Gotoxy 348 | push eax 349 | ; draw a blank space: 350 | mov eax,gray (gray * 16) 351 | call SetTextColor 352 | pop eax 353 | mov al," " 354 | call WriteChar 355 | ret 356 | DeletePlayerPixels ENDP 357 | 358 | ; draw player to current location: 359 | DrawPlayer PROC 360 | push eax 361 | mov eax,white (white * 16) 362 | call SetTextColor 363 | pop eax 364 | 365 | mov dl,xPos 366 | mov dh,yPos 367 | call Gotoxy 368 | mov al,"X" 369 | call WriteChar 370 | ret 371 | DrawPlayer ENDP 372 | 373 | DrawAppleCont PROC 374 | ; draw a red apple: 375 | push eax 376 | mov eax,red (red * 16) 377 | call SetTextColor 378 | pop eax 379 | push edx 380 | mov dl,xApplePos 381 | mov dh,yApplePos 382 | call Gotoxy 383 | pop edx 384 | mov al,"X" 385 | call WriteChar 386 | ret 387 | DrawAppleCont ENDP 388 | 389 | DrawRandomApple PROC 390 | push edx 391 | ; generate random x position: 392 | mov eax,30 393 | call RandomRange 394 | mov dl,al 395 | ; generate random y position: 396 | mov eax,30 397 | call RandomRange 398 | mov dh,al 399 | call Gotoxy 400 | 401 | ; log the apple's position: 402 | mov xApplePos,dl 403 | mov yApplePos,dh 404 | pop edx 405 | ret 406 | DrawRandomApple ENDP 407 | 408 | CheckAppleCollision PROC 409 | ; if apple and player positions are equal, set isColliding to 'T' 410 | mov bl,xPos 411 | cmp xApplePos,bl 412 | jne notColliding 413 | 414 | mov bl,yPos 415 | cmp yApplePos,bl 416 | jne notColliding 417 | mov isColliding,'T' 418 | jmp exitCheck 419 | 420 | ; otherwise set it to 'F' 421 | notColliding: 422 | mov isColliding,'F' 423 | 424 | exitCheck: 425 | ret 426 | CheckAppleCollision ENDP 427 | 428 | END main 429 | --------------------------------------------------------------------------------