Keyboard input/Flush the keyboard buffer: Difference between revisions
Content added Content deleted
(Add task to ARM assembly Raspberry pi) |
(add task to ARM64 assembly Raspberry Pi) |
||
Line 17: | Line 17: | ||
<br><br> |
<br><br> |
||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
|||
<lang AArch64 Assembly> |
|||
/* 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" |
|||
</lang> |
|||
{{output}} |
|||
<pre> |
|||
abcdefg |
|||
help |
|||
kk |
|||
End program OK. |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |