| 1 |
134 |
Agner |
/************************ guess_number.as **********************************
|
| 2 |
|
|
* Author: Agner Fog
|
| 3 |
|
|
* date created: 2018-02-23
|
| 4 |
|
|
* last modified: 2021-08-04
|
| 5 |
|
|
* Version: 1.11
|
| 6 |
|
|
* Project: ForwardCom example, assembly code
|
| 7 |
|
|
* Description: Guessing game. Guess a number 1 - 100
|
| 8 |
|
|
*
|
| 9 |
|
|
* Copyright 2018-2021 GNU General Public License http://www.gnu.org/licenses
|
| 10 |
|
|
*****************************************************************************/
|
| 11 |
|
|
|
| 12 |
|
|
%buffersize = 0x20 // size of input text buffer
|
| 13 |
|
|
%maxnum = 100 // maximum number
|
| 14 |
|
|
|
| 15 |
|
|
const section read ip // read-only data section
|
| 16 |
|
|
intro: int8 "\nGuessing game. Guess a number 1 - %i\n",0 // format string
|
| 17 |
|
|
guess: int8 "Your guess:",0 // text
|
| 18 |
|
|
smaller: int8 "\nSmaller",0 // text
|
| 19 |
|
|
bigger: int8 "\nBigger",0 // text
|
| 20 |
|
|
conclude: int8 "\nYou guessed the number %i in %i tries",0 // format string
|
| 21 |
|
|
another: int8 "\nAnother? (y/n) ",0 // text
|
| 22 |
|
|
goodbye: int8 "\nGoodbye", 0 // text
|
| 23 |
|
|
const end
|
| 24 |
|
|
|
| 25 |
|
|
bss section datap uninitialized // uninitialized read/write data section
|
| 26 |
|
|
int64 parlist[4] // parameter list for printf
|
| 27 |
|
|
int8 buf[buffersize] // input buffer
|
| 28 |
|
|
bss end
|
| 29 |
|
|
|
| 30 |
|
|
code section execute // code section
|
| 31 |
|
|
|
| 32 |
|
|
extern _puts: function // library function: write string to stdout
|
| 33 |
|
|
extern _gets_s: function // library function: read string from stdin
|
| 34 |
|
|
extern _printf: function // library function: formatted output to stdout
|
| 35 |
|
|
extern _atoi: function // library function: convert string to integer
|
| 36 |
|
|
extern _divide_int: function // library function: divide intergers (if core has no division instruction)
|
| 37 |
|
|
|
| 38 |
|
|
_main function public // program begins here
|
| 39 |
|
|
do { // loop to repeat game
|
| 40 |
|
|
int64 r0 = address([intro]) // format string to printf
|
| 41 |
|
|
int64 r1 = address([parlist]) // parameter list
|
| 42 |
|
|
int32 [r1] = maxnum // put maxnum in parameter list
|
| 43 |
|
|
call _printf // printf("\nguess a number 1 - %i\n", maxnum);
|
| 44 |
|
|
int32 r0 = read_perf(perf1,1) // read CPU clock counter to use as a random number
|
| 45 |
|
|
uint32 r0 = abs(r0,1) // avoid negative numbers
|
| 46 |
|
|
//call _time // or use time as random number
|
| 47 |
|
|
// get number modulo maxnum (0 - 99)
|
| 48 |
|
|
//uint32 r1 = r0 % maxnum // use this if core has division instruction
|
| 49 |
|
|
int32 r1 = maxnum
|
| 50 |
|
|
call _divide_int // this function returns a/b in r0 and a%b in r1
|
| 51 |
|
|
|
| 52 |
|
|
int32 r16 = r1 + 1 // number to guess (1 - 100)
|
| 53 |
|
|
for (int64 r17 = 1; ; r17++) { // loop to guess number. no exit condition here
|
| 54 |
|
|
int64 r0 = address([guess])
|
| 55 |
|
|
call _puts // write "your guess"
|
| 56 |
|
|
int64 r0 = address([buf])
|
| 57 |
|
|
int64 r1 = buffersize
|
| 58 |
|
|
call _gets_s // read input into buffer
|
| 59 |
|
|
int64 r0 = address([buf])
|
| 60 |
|
|
call _atoi // convert string to integer
|
| 61 |
|
|
if (int32 r0 == r16) {break} // guess is correct. stop 'for' loop
|
| 62 |
|
|
if (int32 r16 < r0) { // select text: "smaller" or "bigger"
|
| 63 |
|
|
int64 r0 = address([smaller])
|
| 64 |
|
|
}
|
| 65 |
|
|
else {
|
| 66 |
|
|
int64 r0 = address([bigger])
|
| 67 |
|
|
}
|
| 68 |
|
|
call _puts // write "smaller" or "bigger"
|
| 69 |
|
|
}
|
| 70 |
|
|
|
| 71 |
|
|
// guessing loop is finished
|
| 72 |
|
|
int64 r0 = address([conclude]) // format string for printf
|
| 73 |
|
|
int64 r1 = address([parlist]) // parameter list
|
| 74 |
|
|
int32 [r1] = r16 // put guessed number in parameter list
|
| 75 |
|
|
int32 [r1+8] = r17 // put number of tries in parameter list
|
| 76 |
|
|
call _printf // printf("\nyou guessed the number %i in %i tries", r16, r17)
|
| 77 |
|
|
|
| 78 |
|
|
int64 r0 = address([another])
|
| 79 |
|
|
call _puts // write "\nanother? (y/n) "
|
| 80 |
|
|
int64 r0 = address([buf])
|
| 81 |
|
|
int64 r1 = buffersize
|
| 82 |
|
|
call _gets_s // read answer into buffer
|
| 83 |
|
|
int8 r0 = [buf] // get first character of answer, ignore the rest
|
| 84 |
|
|
int8+ r0 |= 0x20 // convert to lower case
|
| 85 |
|
|
}
|
| 86 |
|
|
while (int8 r0 == 'y') // repeat 'do' loop if answer is "y"
|
| 87 |
|
|
|
| 88 |
|
|
int64 r0 = address([goodbye])
|
| 89 |
|
|
call _puts // write "goodbye"
|
| 90 |
|
|
|
| 91 |
|
|
int r0 = 0 // program return value
|
| 92 |
|
|
return // return from main
|
| 93 |
|
|
_main end
|
| 94 |
|
|
|
| 95 |
|
|
code end
|