/* ARM assembly AARCH64 Raspberry PI 3B */ /* program 2048_64.s */ /*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc" .equ SIZE, 4 .equ TOTAL, 2048 .equ BUFFERSIZE, 80 .equ KEYSIZE, 8 .equ IOCTL, 0x1D // Linux syscall .equ SIGACTION, 0x86 // Linux syscall .equ SYSPOLL, 0x16 // Linux syscall .equ CREATPOLL, 0x14 // Linux syscall .equ CTLPOLL, 0x15 // Linux syscall .equ TCGETS, 0x5401 .equ TCSETS, 0x5402 .equ ICANON, 2 .equ ECHO, 10 .equ POLLIN, 1 .equ EPOLL_CTL_ADD, 1 .equ SIGINT, 2 // Issued if the user sends an interrupt signal (Ctrl + C) .equ SIGQUIT, 3 // Issued if the user sends a quit signal (Ctrl + D) .equ SIGTERM, 15 // Software termination signal (sent by kill by default) .equ SIGTTOU, 22 /*******************************************/ /* Structures */ /********************************************/ /* structure termios see doc linux*/ .struct 0 term_c_iflag: // input modes .struct term_c_iflag + 4 term_c_oflag: // output modes .struct term_c_oflag + 4 term_c_cflag: // control modes .struct term_c_cflag + 4 term_c_lflag: // local modes .struct term_c_lflag + 4 term_c_cc: // special characters .struct term_c_cc + 40 // see length if necessary term_fin: /* structure sigaction see doc linux */ .struct 0 sa_handler: .struct sa_handler + 8 sa_mask: .struct sa_mask + 8 sa_flags: .struct sa_flags + 8 sa_sigaction: .struct sa_sigaction + 8 sa_fin: /* structure poll see doc linux */ .struct 0 poll_event: // events mask .struct poll_event + 8 poll_fd: // events returned .struct poll_fd + 8 poll_fin: /*********************************/ /* Initialized data */ /*********************************/ .data szMessOK: .asciz "Bravo !! You win. \n" szMessNotOK: .asciz "You lost !! \n" szMessNewGame: .asciz "New game (y/n) ? \n" szMessErreur: .asciz "Error detected.\n" szMessErrInitTerm: .asciz "Error terminal init.\n" szMessErrInitPoll: .asciz "Error poll init.\n" szMessErreurKey: .asciz "Error read key.\n" szMessErr: .asciz "Error code hexa : @ décimal : @ \n" szCarriageReturn: .asciz "\n" szMess0: .asciz " " szMess2: .asciz " 2 " szMess4: .asciz " 4 " szMess8: .asciz " 8 " szMess16: .asciz " 16 " szMess32: .asciz " 32 " szMess64: .asciz " 64 " szMess128: .asciz " 128 " szMess256: .asciz " 256 " szMess512: .asciz " 512 " szMess1024: .asciz " 1024 " szMess2048: .asciz " 2048 " szCleax1: .byte 0x1B .byte 'c' // other console clear .byte 0 szLineH: .asciz "-----------------------------\n" szLineV: .asciz "|" szLineVT: .asciz "| | | | |\n" .align 4 qGraine: .quad 123456 /*********************************/ /* UnInitialized data */ /*********************************/ .bss .align 4 sZoneConv: .skip 24 sBuffer: .skip BUFFERSIZE qTbCase: .skip 8 * SIZE * SIZE qEnd: .skip 8 // 0 loop 1 = end loop qTouche: .skip KEYSIZE // value key pressed stOldtio: .skip term_fin // old terminal state stCurtio: .skip term_fin // current terminal state stSigAction: .skip sa_fin // area signal structure stSigAction1: .skip sa_fin stSigAction2: .skip sa_fin stSigAction3: .skip sa_fin stPoll1: .skip poll_fin // area poll structure stPoll2: .skip poll_fin stevents: .skip 16 /*********************************/ /* code section */ /*********************************/ .text .global main main: // entry of program mov x0,#0 bl initTerm // terminal init cmp x0,0 // error ? blt 100f bl initPoll // epoll instance init cmp x0,0 blt 99f mov x22,x0 // save epfd 1: // begin game loop ldr x0,qAdrszCleax1 bl affichageMess bl razTable 2: bl addDigit cmp x0,#-1 beq 5f // end game bl displayGame 3: mov x0,x22 bl waitKey cmp x0,0 beq 3b bl readKey cmp x0,#-1 beq 99f // error bl keyMove cmp x0,#0 beq 3b // no change -> loop cmp x0,#2 // last addition = 2048 ? beq 4f cmp x0,#-1 // quit ? bne 2b // loop b 10f 4: // last addition = 2048 ldr x0,qAdrszMessOK bl affichageMess b 10f 5: // display message no solution ldr x0,qAdrszMessNotOK bl affichageMess 10: // display new game ? ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszMessNewGame bl affichageMess 11: mov x0,x22 bl waitKey cmp x0,0 beq 11b bl readKey ldr x0,qAdrqTouche ldrb w0,[x0] cmp w0,#'y' beq 1b cmp w0,#'Y' beq 1b 99: bl restauTerm // terminal restaur 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 qAdrszMessNotOK: .quad szMessNotOK qAdrszMessOK: .quad szMessOK qAdrszMessNewGame: .quad szMessNewGame qAdrsZoneConv: .quad sZoneConv qAdrszCleax1: .quad szCleax1 qAdrszMessErrInitTerm: .quad szMessErrInitTerm qAdrszMessErrInitPoll: .quad szMessErrInitPoll qAdrszMessErreurKey: .quad szMessErreurKey qAdrstOldtio: .quad stOldtio qAdrstCurtio: .quad stCurtio qAdrstSigAction: .quad stSigAction qAdrstSigAction1: .quad stSigAction1 qAdrSIG_IGN: .quad 1 qAdrqEnd: .quad qEnd qAdrqTouche: .quad qTouche qAdrstevents: .quad stevents /******************************************************************/ /* raz table cases */ /******************************************************************/ razTable: stp x0,lr,[sp,-16]! // save registres stp x1,x2,[sp,-16]! // save registres ldr x1,qAdrqTbCase mov x2,#0 1: str xzr,[x1,x2,lsl #3] add x2,x2,#1 cmp x2,#SIZE * SIZE blt 1b 100: ldp x1,x2,[sp],16 // restaur des 2 registres ldp x0,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* key move */ /******************************************************************/ /* x0 contains key value */ keyMove: stp x1,lr,[sp,-16]! // save registres lsr x0,x0,#16 cmp x0,#0x42 // down arrow bne 1f bl moveDown b 100f 1: cmp x0,#0x41 // high arrow bne 2f bl moveUp b 100f 2: cmp x0,#0x43 // right arrow bne 3f bl moveRight b 100f 3: cmp x0,#0x44 // left arrow bne 4f bl moveLeft b 100f 4: ldr x0,qAdrqTouche ldrb w0,[x0] cmp w0,#'q' // quit game bne 5f mov x0,#-1 b 100f 5: cmp w0,#'Q' // quit game bne 100f mov x0,#-1 b 100f 100: ldp x1,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* move left */ /******************************************************************/ /* x0 return -1 if ok */ moveLeft: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres stp x4,x5,[sp,-16]! // save registres stp x6,x7,[sp,-16]! // save registres stp x8,x9,[sp,-16]! // save registres stp x10,x11,[sp,-16]! // save registres ldr x1,qAdrqTbCase mov x0,#0 // top move Ok mov x2,#0 // line indice 1: mov x6,#0 // counter empty case mov x7,#0 // first digit mov x10,#0 // last digit to add mov x3,#0 // column indice 2: lsl x5,x2,#2 // change this if size <> 4 add x5,x5,x3 // compute table indice ldr x4,[x1,x5,lsl #3] cmp x4,#0 cinc x6,x6,eq // positions vides beq 5f cmp x6,#0 beq 3f // no empty left case mov x8,#0 str x8,[x1,x5,lsl #3] // raz digit sub x5,x5,x6 str x4,[x1,x5,lsl #3] // and store to left empty position mov x0,#1 // move Ok 3: cmp x7,#0 // first digit beq 4f cmp x10,x4 // prec digit have to add beq 4f sub x8,x5,#1 // prec digit ldr x9,[x1,x8,lsl #3] cmp x4,x9 // equal ? bne 4f mov x10,x4 // save digit add x4,x4,x9 // yes -> add str x4,[x1,x8,lsl #3] cmp x4,#TOTAL beq 6f mov x4,#0 str x4,[x1,x5,lsl #3] add x6,x6,#1 // empty case + 1 mov x0,#1 // move Ok 4: add x7,x7,#1 // no first digit 5: // and loop add x3,x3,#1 cmp x3,#SIZE blt 2b add x2,x2,#1 cmp x2,#SIZE blt 1b b 100f 6: mov x0,#2 // total = 2048 100: ldp x10,x11,[sp],16 // restaur des 2 registres ldp x8,x9,[sp],16 // restaur des 2 registres ldp x6,x7,[sp],16 // restaur des 2 registres ldp x4,x5,[sp],16 // restaur des 2 registres ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* move right */ /******************************************************************/ /* x0 return -1 if ok */ moveRight: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres stp x4,x5,[sp,-16]! // save registres stp x6,x7,[sp,-16]! // save registres stp x8,x9,[sp,-16]! // save registres stp x10,x11,[sp,-16]! // save registres ldr x1,qAdrqTbCase mov x0,#0 mov x2,#0 1: mov x6,#0 mov x7,#0 mov x10,#0 mov x3,#SIZE-1 2: lsl x5,x2,#2 // change this if size <> 4 add x5,x5,x3 ldr x4,[x1,x5,lsl #3] cmp x4,#0 cinc x6,x6,eq // positions vides beq 5f cmp x6,#0 beq 3f // no empty right case mov x0,#0 str x0,[x1,x5,lsl #3] // raz digit add x5,x5,x6 str x4,[x1,x5,lsl #3] // and store to right empty position mov x0,#1 3: cmp x7,#0 // first digit beq 4f add x8,x5,#1 // next digit ldr x9,[x1,x8,lsl #3] cmp x4,x9 // equal ? bne 4f cmp x10,x4 beq 4f mov x10,x4 add x4,x4,x9 // yes -> add str x4,[x1,x8,lsl #3] cmp x4,#TOTAL beq 6f mov x4,#0 str x4,[x1,x5,lsl #3] add x6,x6,#1 // empty case + 1 mov x0,#1 4: add x7,x7,#1 // no first digit 5: // and loop sub x3,x3,#1 cmp x3,#0 bge 2b add x2,x2,#1 cmp x2,#SIZE blt 1b b 100f 6: mov x0,#2 100: ldp x10,x11,[sp],16 // restaur des 2 registres ldp x8,x9,[sp],16 // restaur des 2 registres ldp x6,x7,[sp],16 // restaur des 2 registres ldp x4,x5,[sp],16 // restaur des 2 registres ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* move down */ /******************************************************************/ /* x0 return -1 if ok */ moveDown: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres stp x4,x5,[sp,-16]! // save registres stp x6,x7,[sp,-16]! // save registres stp x8,x9,[sp,-16]! // save registres stp x10,x11,[sp,-16]! // save registres ldr x1,qAdrqTbCase mov x0,#0 mov x3,#0 1: mov x6,#0 mov x7,#0 mov x10,#0 mov x2,#SIZE-1 2: lsl x5,x2,#2 // change this if size <> 4 add x5,x5,x3 ldr x4,[x1,x5,lsl #3] cmp x4,#0 cinc x6,x6,eq // positions vides beq 5f cmp x6,#0 beq 3f // no empty right case mov x0,#0 str x0,[x1,x5,lsl #3] // raz digit lsl x0,x6,#2 add x5,x5,x0 str x4,[x1,x5,lsl #3] // and store to right empty position mov x0,#1 3: cmp x7,#0 // first digit beq 4f add x8,x5,#SIZE // down digit ldr x9,[x1,x8,lsl #3] cmp x4,x9 // equal ? bne 4f cmp x10,x4 beq 4f mov x10,x4 add x4,x4,x9 // yes -> add str x4,[x1,x8,lsl #3] cmp x4,#TOTAL beq 6f mov x4,#0 str x4,[x1,x5,lsl #3] add x6,x6,#1 // empty case + 1 mov x0,#1 4: add x7,x7,#1 // no first digit 5: // and loop sub x2,x2,#1 cmp x2,#0 bge 2b add x3,x3,#1 cmp x3,#SIZE blt 1b b 100f 6: mov x0,#2 100: ldp x10,x11,[sp],16 // restaur des 2 registres ldp x8,x9,[sp],16 // restaur des 2 registres ldp x6,x7,[sp],16 // restaur des 2 registres ldp x4,x5,[sp],16 // restaur des 2 registres ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* move up */ /******************************************************************/ /* x0 return -1 if ok */ moveUp: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres stp x4,x5,[sp,-16]! // save registres stp x6,x7,[sp,-16]! // save registres stp x8,x9,[sp,-16]! // save registres stp x10,x11,[sp,-16]! // save registres ldr x1,qAdrqTbCase mov x0,#0 mov x3,#0 1: mov x6,#0 mov x7,#0 mov x10,#0 mov x2,#0 2: lsl x5,x2,#2 // change this if size <> 4 add x5,x5,x3 ldr x4,[x1,x5,lsl #3] cmp x4,#0 cinc x6,x6,eq // positions vides beq 5f cmp x6,#0 beq 3f // no empty right case mov x0,#0 str x0,[x1,x5,lsl #3] // raz digit lsl x0,x6,#2 sub x5,x5,x0 str x4,[x1,x5,lsl #3] // and store to right empty position mov x0,#1 3: cmp x7,#0 // first digit beq 4f sub x8,x5,#SIZE // up digit ldr x9,[x1,x8,lsl #3] cmp x4,x9 // equal ? bne 4f cmp x10,x4 beq 4f mov x10,x4 add x4,x4,x9 // yes -> add str x4,[x1,x8,lsl #3] cmp x4,#TOTAL beq 6f mov x4,#0 str x4,[x1,x5,lsl #3] add x6,x6,#1 // empty case + 1 mov x0,#1 4: add x7,x7,#1 // no first digit 5: // and loop add x2,x2,#1 cmp x2,#SIZE blt 2b add x3,x3,#1 cmp x3,#SIZE blt 1b b 100f 6: mov x0,#2 100: ldp x10,x11,[sp],16 // restaur des 2 registres ldp x8,x9,[sp],16 // restaur des 2 registres ldp x6,x7,[sp],16 // restaur des 2 registres ldp x4,x5,[sp],16 // restaur des 2 registres ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret /******************************************************************/ /* add new digit on game */ /******************************************************************/ /* x0 return -1 if ok */ addDigit: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres stp x4,x5,[sp,-16]! // save registres sub sp,sp,#8 * SIZE*SIZE mov fp,sp mov x0,#100 bl genereraleas cmp x0,#10 mov x1,#4 mov x5,#2 csel x5,x5,x1,ge // movlt x5,#4 //movge x5,#2 ldr x1,qAdrqTbCase mov x3,#0 mov x4,#0 1: ldr x2,[x1,x3,lsl 3] cmp x2,#0 bne 2f str x3,[fp,x4,lsl 3] add x4,x4,#1 2: add x3,x3,#1 cmp x3,#SIZE*SIZE blt 1b cmp x4,#0 // no empty case beq 4f cmp x4,#1 bne 3f ldr x2,[fp] // one case str x5,[x1,x2,lsl 3] mov x0,#0 b 100f 3: // multiple case sub x0,x4,#1 bl genereraleas ldr x2,[fp,x0,lsl 3] str x5,[x1,x2,lsl 3] mov x0,#0 b 100f 4: mov x0,#-1 100: add sp,sp,#8* (SIZE*SIZE) // stack alignement ldp x4,x5,[sp],16 // restaur des 2 registres ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret qAdrqTbCase: .quad qTbCase /******************************************************************/ /* display game */ /******************************************************************/ displayGame: stp x1,lr,[sp,-16]! // save registres stp x2,x3,[sp,-16]! // save registres ldr x0,qAdrszCleax1 bl affichageMess ldr x0,qAdrszLineH bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineV bl affichageMess ldr x1,qAdrqTbCase mov x2,#0 1: ldr x0,[x1,x2,lsl #3] bl digitString bl affichageMess ldr x0,qAdrszLineV bl affichageMess add x2,x2,#1 cmp x2,#SIZE blt 1b ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineH bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineV bl affichageMess 2: ldr x0,[x1,x2,lsl #3] bl digitString bl affichageMess ldr x0,qAdrszLineV bl affichageMess add x2,x2,#1 cmp x2,#SIZE*2 blt 2b ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineH bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineV bl affichageMess 3: ldr x0,[x1,x2,lsl #3] bl digitString bl affichageMess ldr x0,qAdrszLineV bl affichageMess add x2,x2,#1 cmp x2,#SIZE*3 blt 3b ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineH bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineV bl affichageMess 4: ldr x0,[x1,x2,lsl #3] bl digitString bl affichageMess ldr x0,qAdrszLineV bl affichageMess add x2,x2,#1 cmp x2,#SIZE*4 blt 4b ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszLineVT bl affichageMess ldr x0,qAdrszLineH bl affichageMess 100: ldp x2,x3,[sp],16 // restaur des 2 registres ldp x1,lr,[sp],16 // restaur des 2 registres ret qAdrszLineH: .quad szLineH qAdrszLineV: .quad szLineV qAdrszLineVT: .quad szLineVT /******************************************************************/ /* digits string */ /******************************************************************/ /* x0 contains number */ /* x0 return address string */ digitString: stp x1,lr,[sp,-16]! // save registres cmp x0,#0 bne 1f ldr x0,qAdrszMess0 b 100f 1: cmp x0,#2 bne 2f ldr x0,qAdrszMess2 b 100f 2: cmp x0,#4 bne 3f ldr x0,qAdrszMess4 b 100f 3: cmp x0,#8 bne 4f ldr x0,qAdrszMess8 b 100f 4: cmp x0,#16 bne 5f ldr x0,qAdrszMess16 b 100f 5: cmp x0,#32 bne 6f ldr x0,qAdrszMess32 b 100f 6: cmp x0,#64 bne 7f ldr x0,qAdrszMess64 b 100f 7: cmp x0,#128 bne 8f ldr x0,qAdrszMess128 b 100f 8: cmp x0,#256 bne 9f ldr x0,qAdrszMess256 b 100f 9: cmp x0,#512 bne 10f ldr x0,qAdrszMess512 b 100f 10: cmp x0,#1024 bne 11f ldr x0,qAdrszMess1024 b 100f 11: cmp x0,#2048 bne 12f ldr x0,qAdrszMess2048 b 100f 12: ldr x1,qAdrszMessErreur // error message bl displayError 100: ldp x1,lr,[sp],16 // restaur des 2 registres ret qAdrszMess0: .quad szMess0 qAdrszMess2: .quad szMess2 qAdrszMess4: .quad szMess4 qAdrszMess8: .quad szMess8 qAdrszMess16: .quad szMess16 qAdrszMess32: .quad szMess32 qAdrszMess64: .quad szMess64 qAdrszMess128: .quad szMess128 qAdrszMess256: .quad szMess256 qAdrszMess512: .quad szMess512 qAdrszMess1024: .quad szMess1024 qAdrszMess2048: .quad szMess2048 //qAdrsBuffer: .quad sBuffer qAdrszMessErreur : .quad szMessErreur /***************************************************/ /* Generation random number */ /***************************************************/ /* x0 contains limit */ genereraleas: stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers ldr x1,qAdrqGraine ldr x2,[x1] ldr x3,qNbDep1 mul x2,x3,x2 ldr x3,qNbDep2 add x2,x2,x3 str x2,[x1] // 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 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 /******************************************************************/ /* traitement du signal */ /******************************************************************/ sighandler: stp x0,lr,[sp,-16]! // save registers str x1,[sp,-16]! ldr x0,qAdrqEnd mov x1,#1 // maj zone end str x1,[x0] ldr x1,[sp],16 ldp x0,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /***************************************************/ /* display error message */ /***************************************************/ /* x0 contains error code x1 : message address */ displayError: stp x2,lr,[sp,-16]! // save registers mov x2,x0 // save error code mov x0,x1 bl affichageMess mov x0,x2 // error code ldr x1,qAdrsZoneConv bl conversion16 // conversion hexa ldr x0,qAdrszMessErr // display error message ldr x1,qAdrsZoneConv bl strInsertAtCharInc // insert result at @ character mov x3,x0 mov x0,x2 // error code ldr x1,qAdrsZoneConv // result address bl conversion10S // conversion decimale mov x0,x3 ldr x1,qAdrsZoneConv bl strInsertAtCharInc // insert result at @ character bl affichageMess 100: ldp x2,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 qAdrszMessErr: .quad szMessErr /*********************************/ /* init terminal state */ /*********************************/ initTerm: stp x1,lr,[sp,-16]! // save registers /* read terminal state */ mov x0,STDIN // input console mov x1,TCGETS ldr x2,qAdrstOldtio mov x8,IOCTL // call system Linux svc 0 cbnz x0,98f // error ? adr x0,sighandler // adresse routine traitement signal ldr x1,qAdrstSigAction // adresse structure sigaction str x0,[x1,sa_handler] // maj handler mov x0,SIGINT // signal type ldr x1,qAdrstSigAction mov x2,0 mov x3,8 mov x8,SIGACTION // call system svc 0 cmp x0,0 // error ? bne 98f mov x0,SIGQUIT ldr x1,qAdrstSigAction mov x2,0 // NULL mov x8,SIGACTION // call system svc 0 cmp x0,0 // error ? bne 98f mov x0,SIGTERM ldr x1,qAdrstSigAction mov x2,0 // NULL mov x8,SIGACTION // appel systeme svc 0 cmp x0,0 bne 98f // adr x0,qAdrSIG_IGN // address signal igonre function ldr x1,qAdrstSigAction1 str x0,[x1,sa_handler] mov x0,SIGTTOU //invalidate other process signal ldr x1,qAdrstSigAction1 mov x2,0 // NULL mov x8,SIGACTION // call system svc 0 cmp x0,0 bne 98f // /* read terminal current state */ mov x0,STDIN mov x1,TCGETS ldr x2,qAdrstCurtio // address current termio mov x8,IOCTL // call systeme svc 0 cmp x0,0 // error ? bne 98f mov x2,ICANON | ECHO // no key pressed echo on display mvn x2,x2 // and one key ldr x1,qAdrstCurtio ldr x3,[x1,#term_c_lflag] and x3,x2,x2 // add flags str x3,[x1,#term_c_lflag] // and store mov x0,STDIN // maj terminal current state mov x1,TCSETS ldr x2,qAdrstCurtio mov x8,IOCTL // call system svc 0 cbz x0,100f 98: // error display ldr x1,qAdrszMessErrInitTerm bl displayError mov x0,-1 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 qAdrstSigAction2: .quad stSigAction2 qAdrstSigAction3: .quad stSigAction3 /*********************************/ /* init instance epool */ /*********************************/ initPoll: stp x1,lr,[sp,-16]! // save registers ldr x0,qAdrstevents mov x1,STDIN // maj structure events str x1,[x0,#poll_fd] // maj FD mov x1,POLLIN // action code str x1,[x0,#poll_event] mov x0,0 mov x8,CREATPOLL // create epoll instance svc 0 cmp x0,0 // error ? ble 98f mov x10,x0 // return FD epoll instance mov x1,EPOLL_CTL_ADD mov x2,STDIN // Fd to we want add ldr x3,qAdrstevents // structure events address mov x8,CTLPOLL // call system control epoll svc 0 cmp x0,0 // error ? blt 98f // no mov x0,x10 // return FD epoll instance b 100f 98: // error display ldr x1,qAdrszMessErrInitPoll // error message bl displayError mov x0,-1 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /*********************************/ /* wait key */ /*********************************/ /* x0 contains FD poll */ waitKey: stp x1,lr,[sp,-16]! // save registers ldr x11,qAdrqTouche // key address str xzr,[x11] // raz key 1: ldr x1,qAdrqEnd // if signal ctrl-c -> end ldr x1,[x1] cbnz x1,100f ldr x1,qAdrstevents mov x2,12 // size events mov x3,1 // timeout = 1 TODO: ?? mov x4,0 mov x8,SYSPOLL // call system wait POLL svc 0 cmp x0,0 // key pressed ? bge 100f 98: // error display ldr x1,qAdrszMessErreurKey // error message bl displayError mov x0,-1 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /*********************************/ /* read key */ /*********************************/ /* x0 returns key value */ readKey: stp x1,lr,[sp,-16]! // save registers mov x0,STDIN // File Descriptor ldr x1,qAdrqTouche // buffer address mov x2,KEYSIZE // key size mov x8,READ // read key svc #0 cmp x0,0 // error ? ble 98f ldr x2,qAdrqTouche // key address ldr x0,[x2] b 100f 98: // error display ldr x1,qAdrszMessErreur // error message bl displayError mov x0,-1 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /*********************************/ /* restaur terminal state */ /*********************************/ restauTerm: stp x1,lr,[sp,-16]! // save registers mov x0,STDIN // end then restaur begin state terminal mov x1,TCSETS ldr x2,qAdrstOldtio mov x8,IOCTL // call system svc 0 cbz x0,100f ldr x1,qAdrszMessErreur // error message bl displayError 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc"