RosettaCodeData/Task/21-game/AArch64-Assembly/21-game.aarch64
2023-07-01 13:44:08 -04:00

217 lines
7.2 KiB
Text

/* ARM assembly AARCH64 Raspberry PI 3B */
/* program game21_64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ HITTOTAL, 21
.equ BUFFERSIZE, 10
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessRules: .ascii "21 Game\n"
.ascii "21 is a two player game, the game is played by choosing a number \n"
.ascii "(1, 2, or 3) to be added to the running total. The game is won by\n"
.ascii "the player whose chosen number causes the running total to reach \n"
.asciz "exactly 21. The running total starts at zero.\n\n\n"
szMessHumanChoice: .asciz "Enter your choice (1,2, 3 or type (q)uit to exit): "
szMessErrChoise: .asciz "invalid choice.\n "
szMessHumanBegin: .asciz "The first move is human move.\n"
szMessPiBegin: .asciz "The first move is Raspberry pi. \n"
szMessHumanWon: .asciz "You won. \n"
szMessHumanLost: .asciz "You lost. \n"
szMessTotal: .asciz "The running total is @ \n"
szMessPiChoice: .asciz "Raspberry choice is @ \n"
szMessNewGame: .asciz "New game (y/n) ? \n"
szCarriageReturn: .asciz "\n"
.align 4
qGraine: .quad 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessRules
bl affichageMess
1:
mov x10,#0 // total = 0
mov x0,#100
bl genereraleas
cmp x0,#50
blt 2f
ldr x0,qAdrszMessHumanBegin // human begin
bl affichageMess
b 4f
2: // Rasp begin
ldr x0,qAdrszMessPiBegin
bl affichageMess
mov x0,#1
3: // rasp turn
add x10,x10,x0
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
ldr x0,qAdrszMessPiChoice
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess
cmp x10,#HITTOTAL
bne 4f
ldr x0,qAdrszMessHumanLost
bl affichageMess
b 12f
4: // display current total
mov x0,x10
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
ldr x0,qAdrszMessTotal
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess
5: // human turn
ldr x0,qAdrszMessHumanChoice
bl affichageMess
bl saisie
cmp x0,#'q' // quit ?
beq 100f
cmp x0,#'Q'
beq 100f
cmp x0,#'1'
add x9,x10,1
csel x10,x9,x10,eq
beq 6f
cmp x0,#'2'
add x9,x10,2
csel x10,x9,x10,eq
beq 6f
cmp x0,#'3'
add x9,x10,3
csel x10,x9,x10,eq
beq 6f
ldr x0,qAdrszMessErrChoise
bl affichageMess
b 5b
6:
cmp x10,#HITTOTAL // total = maxi ?
beq 11f // yes -> human won
cmp x10,#5 // else compute rasp number
mov x9,5 // compare total and optimun
7:
cmp x10,x9
ble 8f
add x9,x9,4
b 7b
8:
sub x0,x9,x10 // compute number rasp
9: // control number rasp
cmp x0,#0
ble 10f
cmp x0,#3
ble 3b
10: // if not ok, generate random number
mov x0,#2
bl genereraleas
add x0,x0,#1
b 3b // and loop
11: // display human won
ldr x0,qAdrszMessHumanWon
bl affichageMess
12: // display new game ?
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszMessNewGame
bl affichageMess
bl saisie
cmp x0,#'y'
beq 1b
cmp x0,#'Y'
beq 1b
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessRules: .quad szMessRules
qAdrszMessHumanBegin: .quad szMessHumanBegin
qAdrszMessPiBegin: .quad szMessPiBegin
qAdrszMessPiChoice: .quad szMessPiChoice
qAdrszMessTotal: .quad szMessTotal
qAdrszMessHumanChoice: .quad szMessHumanChoice
qAdrszMessHumanLost: .quad szMessHumanLost
qAdrszMessHumanWon: .quad szMessHumanWon
qAdrszMessNewGame: .quad szMessNewGame
qAdrszMessErrChoise: .quad szMessErrChoise
qAdrsZoneConv: .quad sZoneConv
/******************************************************************/
/* string saisie */
/******************************************************************/
/* x0 return the first character of human entry */
saisie:
stp x1,lr,[sp,-16]! // save registers
stp x2,x8,[sp,-16]! // save registers
mov x0,#STDIN // Linux input console
ldr x1,qAdrsBuffer // buffer address
mov x2,#BUFFERSIZE // buffer size
mov x8,#READ // request to read datas
svc 0 // call system
ldr x1,qAdrsBuffer // buffer address
ldrb w0,[x1] // load first character
100:
ldp x2,x8,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrsBuffer: .quad sBuffer
/***************************************************/
/* Generation random number */
/***************************************************/
/* x0 contains limit */
genereraleas:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
ldr x4,qAdrqGraine
ldr x2,[x4]
ldr x3,qNbDep1
mul x2,x3,x2
ldr x3,qNbDep2
add x2,x2,x3
str x2,[x4] // maj de la graine pour l appel suivant
cmp x0,#0
beq 100f
udiv x3,x2,x0
msub x0,x3,x0,x2 // résult = remainder
100: // end function
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/*****************************************************/
qAdrqGraine: .quad qGraine
qNbDep1: .quad 0x0019660d
qNbDep2: .quad 0x3c6ef35f
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"