Flush the   keyboard   buffer.

This reads characters from the keyboard input and
discards them until there are no more currently buffered,  
and then allows the program to continue.

The program must not wait for users to type anything.

 
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program keyboardInput64.s   */
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.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    // 
 
.equ BUFSIZE,   80
 
/*******************************************/
/* 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 + 20      // 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:
    .struct  poll_event + 8
poll_fd:                            //   File Descriptor
    .struct  poll_fd + 8 
poll_fin:
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessPgmOk:        .asciz "End program OK.\n"
szMessErreur:       .asciz "Error detected.\n"
szCarriageReturn:   .asciz "\n"
szMessCodeErr:      .asciz "Error code décimal :  @ \n"
 
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
.align 4
iEnd:           .skip 8                          // 0 loop  1 = end loop
iTouche:        .skip BUFSIZE                    // 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
stevents:       .skip 16
sZoneConv:      .skip 24
szBuffer:       .skip BUFSIZE
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                     // entry of program 
    bl initTerm                           // terminal init
    cmp x0,0                              // error ?
    blt 100f
    bl initPoll                           // epoll instance init
    cmp x0,0
    blt 100f
    mov x22,x0                            // save epfd
    mov x20,0                             // indice
    ldr x21,qAdrszBuffer
1:
    mov x0,x22                            // epfd
    bl waitKey
    cmp x0,0
    beq 1b                                // no ket pressed -> loop
    blt 3f                                // error ?
 
    bl readKey                            // read one key
    cmp x0,3                              // ctrl-C
    beq 3f
    cmp x0,113                            // saisie q (quit) ?
    beq 3f
    cmp x0,81                             // saisie Q  (Quit)?
    beq 3f
    cmp x0,0xD                            // <enter> ?
    beq 2f
    strb w0,[x21,x20]                     // store byte in buffer
    add x20,x20,1                         // increment indice
    b 1b                                  // and loop
2:                                        // display buffer
    mov x0,0                              // store 0 final
    strb w0,[x21,x20]
    mov x0,x21                            // display buffer
    bl affichageMess
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
    mov x20,0
    b 1b                                  // and loop for other entry
3:
    bl restauTerm                         // terminal restaur
    ldr x0,qAdrszMessPgmOk                // display end message
    bl affichageMess
100:                                      // standard end of the program 
    mov x0,0                              // return code
    mov x8,EXIT                           // request to exit program
    svc 0                                 // perform the system call
qAdrszBuffer:             .quad szBuffer
qAdrstevents:             .quad stevents
qAdrszMessErreur:         .quad szMessErreur
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrstOldtio:             .quad stOldtio
qAdrstCurtio:             .quad stCurtio
qAdrstSigAction:          .quad stSigAction
qAdrstSigAction1:         .quad stSigAction1
qAdrszMessPgmOk:          .quad szMessPgmOk
qAdrSIG_IGN:              .quad 1
qAdriEnd:                 .quad iEnd
qAdriTouche:              .quad iTouche
/*********************************/
/* 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,qAdrszMessErreur        // error message
    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,qAdrszMessErreur                       // 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,qAdriTouche            // key address
    str xzr,[x11]                  // raz key
1:
    ldr x10,qAdriEnd               // if signal ctrl-c  -> end
    ldr x10,[x10]
    cbnz x10,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,qAdrszMessErreur        // 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,qAdriTouche             // buffer address
    mov x2,BUFSIZE                 // buffer size
    mov x8,READ                    // read key
    svc #0
    cmp x0,0                       // error ?
    ble 98f
    ldr x2,qAdriTouche             // key address
    ldr x0,[x2]
    b 100f
98:                                // error display
    ldr x1,qAdrszMessErreur        // error message
    bl   displayError
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
 
/******************************************************************/
/*     signal processing                                     */ 
/******************************************************************/
sighandler:
    stp x1,lr,[sp,-16]!            // save  registers
    ldr x0,qAdriEnd
    mov x1,#1                      // maj zone end
    str x1,[x0]
    ldp x1,lr,[sp],16              // restaur  2 registers
    ret                            // return to address lr x30
/******************************************************************/
/*     display error message                                      */ 
/******************************************************************/
/* x0 contains error code */
/* x1 contains address error message    */
displayError:
    stp x2,lr,[sp,-16]!            // save  registers
    mov x2,x0                      // save error code
    mov x0,x1                      // display message error
    bl affichageMess
    mov x0,x2
    ldr x1,qAdrsZoneConv           // conversion error code
    bl conversion10S               // decimal conversion
    ldr x0,qAdrszMessCodeErr
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc          // insert result at @ character
    bl affichageMess               // display message final
    ldp x2,lr,[sp],16              // restaur  2 registers
    ret                            // return to address lr x30
qAdrsZoneConv:        .quad sZoneConv
qAdrszMessCodeErr:    .quad szMessCodeErr
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 