531 lines
18 KiB
Plaintext
531 lines
18 KiB
Plaintext
/* Programme assembleur ARM Raspberry ou Android */
|
|
/* programme animletter64.s */
|
|
/* REMARK: This program was written for android with the termux app.
|
|
It works very well on raspberry pi but in this case the memory access relocation instructions
|
|
can be simplified.
|
|
|
|
For simplicity, this program does not use X11 structure definitions.
|
|
*/
|
|
|
|
/*******************************************/
|
|
/* Constantes file */
|
|
/*******************************************/
|
|
/* for this file see task include a file in language AArch64 assembly*/
|
|
.include "../includeConstantesARM64.inc"
|
|
|
|
/* constantes X11 */
|
|
.equ KeyPressed, 2
|
|
.equ ButtonPress, 4
|
|
.equ MotionNotify, 6
|
|
.equ EnterNotify, 7
|
|
.equ LeaveNotify, 8
|
|
.equ Expose, 12
|
|
.equ ClientMessage, 33
|
|
.equ KeyPressMask, 1
|
|
.equ ButtonPressMask, 4
|
|
.equ ButtonReleaseMask, 8
|
|
.equ ExposureMask, 1<<15
|
|
.equ StructureNotifyMask, 1<<17
|
|
.equ EnterWindowMask, 1<<4
|
|
.equ LeaveWindowMask, 1<<5
|
|
.equ ConfigureNotify, 22
|
|
|
|
.equ GCForeground, 1<<2
|
|
.equ GCBackground, 1<<3
|
|
.equ GCLine_width, 1<<4
|
|
.equ GCLine_style, 1<<5
|
|
.equ GCFont, 1<<14
|
|
|
|
.equ CWBackPixel, 1<<1
|
|
.equ CWBorderPixel, 1<<3
|
|
.equ CWEventMask, 1<<11
|
|
.equ CWX, 1<<0
|
|
.equ CWY, 1<<1
|
|
.equ CWWidth, 1<<2
|
|
.equ CWHeight, 1<<3
|
|
.equ CWBorderWidth, 1<<4
|
|
.equ CWSibling, 1<<5
|
|
.equ CWStackMode, 1<<6
|
|
|
|
|
|
/* constantes program */
|
|
.equ WINDOWWIDTH, 400
|
|
.equ WINDOWHEIGHT, 300
|
|
|
|
/*********************************/
|
|
/* initialized datas */
|
|
/*********************************/
|
|
.data
|
|
szWindowName: .asciz "Windows Raspberry"
|
|
szRetourLigne: .asciz "\n"
|
|
szMessDebutPgm: .asciz "Program start. \n"
|
|
szMessFinPgm: .asciz "Program end OK.\n"
|
|
szMessErreur: .asciz "Server X not found.\n"
|
|
szMessErrfen: .asciz "Can not create window.\n"
|
|
szMessErreurX11: .asciz "Error call function X11. \n"
|
|
szMessErrGc: .asciz "Can not create graphics context.\n"
|
|
szTitreFenRed: .asciz "Pi"
|
|
szTexte1: .asciz "Hello world! "
|
|
.equ LGTEXTE1, . - szTexte1
|
|
|
|
szLibDW: .asciz "WM_DELETE_WINDOW" // special label for correct close error
|
|
|
|
.align 8
|
|
stXGCValues: .quad 0,0,0xFFA0A0A0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // for foreground color gris1
|
|
//stXGCValues: .quad 0,0,0x00000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // for foreground color black
|
|
stXGCValues1: .quad 0,0,0x00FFFFFF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // for foreground color white
|
|
stXGCValues2: .quad 0,0,0x0000FF00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // for foreground color green
|
|
|
|
|
|
/*********************************/
|
|
/* no initialized datas */
|
|
/*********************************/
|
|
.bss
|
|
.align 8
|
|
sZoneConv: .skip 24
|
|
qDisplay: .skip 8 // Display address
|
|
qEcran: .skip 8 // Screen address
|
|
ptGC1: .skip 8 // Graphic Context pointer
|
|
qSens: .skip 8 // direction
|
|
qKey: .skip 8 // touch value
|
|
wmDeleteMessage: .skip 8 // ident close message
|
|
stEvent: .skip 400 // event structure
|
|
sBuffer: .skip 80
|
|
sbuffer1: .skip 80
|
|
/*********************************/
|
|
/* code section */
|
|
/*********************************/
|
|
.text
|
|
.global main
|
|
main: // programm entry
|
|
adr x0,qOfszMessDebutPgm
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
/* Attention x28 display address
|
|
x27 window ident
|
|
x26 ident GC1
|
|
x24 ident GC2
|
|
*/
|
|
mov x0,#0 // open X server
|
|
bl XOpenDisplay
|
|
cbz x0,99f // no X server ?
|
|
|
|
adr x1,qOfqDisplay // ok
|
|
ldr x2,[x1]
|
|
add x2,x2,x1
|
|
str x0,[x2] // store DISPLAY address
|
|
mov x28,x0 // and register 28
|
|
ldr x2,[x0,264] // load screen address in display structure
|
|
adr x3,qOfqEcran
|
|
ldr x1,[x3]
|
|
add x1,x1,x3
|
|
str x2,[x1] // store default_screen
|
|
|
|
mov x2,x0
|
|
ldr x0,[x2,#232] // screens list address
|
|
ldr x5,[x0,#+88] // white pixel
|
|
ldr x3,[x0,#+96] // black pixel
|
|
ldr x4,[x0,#+56] // bits par pixel
|
|
ldr x1,[x0,#+16] // root windows
|
|
/*****************************/
|
|
/* WINDOW CREATION */
|
|
/*****************************/
|
|
mov x0,x28 // display address
|
|
mov x2,#10 // position X
|
|
mov x3,#20 // position Y
|
|
mov x4,WINDOWWIDTH // width
|
|
mov x5,WINDOWHEIGHT // height
|
|
mov x6,1 // bordure width
|
|
mov x7,0 // pixel bordure = black
|
|
ldr x8,qGris1 // background color
|
|
str x8,[sp,-16]! // by stack parameter
|
|
bl XCreateSimpleWindow
|
|
add sp,sp,16 // stack alignement (one parameter)
|
|
cbz x0,98f // create error ?
|
|
mov x27,x0 // save ident window
|
|
|
|
/*****************************/
|
|
/* add window property */
|
|
/*****************************/
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window address
|
|
adr x2,qOfszWindowName // window name
|
|
ldr x5,[x2]
|
|
add x2,x2,x5
|
|
adr x3,qOfszTitreFenRed // window name reduced
|
|
ldr x5,[x3]
|
|
add x3,x3,x5
|
|
mov x4,#0 // parameters not use
|
|
mov x5,#0
|
|
mov x6,#0
|
|
mov x7,#0
|
|
bl XSetStandardProperties
|
|
/**************************************/
|
|
/* for correction window close error */
|
|
/**************************************/
|
|
mov x0,x28 // display address
|
|
adr x1,qOfszLibDW // atom address
|
|
ldr x5,[x1]
|
|
add x1,x1,x5
|
|
mov x2,#1 // False créate atom if not exists
|
|
bl XInternAtom
|
|
cmp x0,#0 // error X11 ?
|
|
ble 97f // Modif avril 22 pour android (ble pour raspberry)
|
|
adr x1,qOfwmDeleteMessage // recept address
|
|
ldr x5,[x1]
|
|
add x1,x1,x5
|
|
str x0,[x1]
|
|
mov x2,x1 // return address
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window address
|
|
mov x3,#1 // number of protocols
|
|
bl XSetWMProtocols
|
|
cmp x0,#0 // error X11 ?
|
|
ble 97f
|
|
|
|
mov x0,x28 // Display address
|
|
mov x1,x27 // window ident
|
|
bl creationGC
|
|
/****************************/
|
|
/* window display on screen */
|
|
/****************************/
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window ident
|
|
bl XMapWindow
|
|
|
|
// authorization of seizures
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window ident
|
|
ldr x2,qSaisieMask // autorizations mask
|
|
bl XSelectInput
|
|
|
|
adr x0,qOfszTexte1 // string address
|
|
ldr x4,[x0]
|
|
add x0,x0,x4
|
|
adr x1,qOfsbuffer1 // buffer address
|
|
ldr x4,[x1]
|
|
add x1,x1,x4
|
|
mov x2,#0
|
|
1: // loop copy character
|
|
ldrb w3,[x0,x2]
|
|
strb w3,[x1,x2]
|
|
cmp x3,#0
|
|
beq 2f
|
|
add x2,x2,#1
|
|
b 1b
|
|
2:
|
|
/****************************/
|
|
/* Events loop */
|
|
/****************************/
|
|
3:
|
|
mov x0,x28 // display address
|
|
bl XPending // loading the number of events
|
|
cmp x0,#0
|
|
bne 4f // a event is occurring
|
|
adr x3,qOfsbuffer1
|
|
ldr x5,[x3]
|
|
add x3,x3,x5
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window ident
|
|
mov x2,x26 // graphic context
|
|
bl animate // string display and move
|
|
b 3b // and loop
|
|
|
|
4:
|
|
mov x0,x28 // adresse du display
|
|
adr x1,qOfstEvent // adresse structure evenements
|
|
ldr x2,[x1]
|
|
add x1,x1,x2
|
|
mov x25,x1 // save adresse structure evenement
|
|
bl XNextEvent
|
|
|
|
ldr w0,[x25] // code évenement
|
|
cmp x0,#KeyPressed // appui touche ?
|
|
bne 5f
|
|
// cas d'une touche
|
|
mov x0,x25
|
|
adr x1,qOfsBuffer // adresse buffer
|
|
ldr x2,[x1]
|
|
add x1,x1,x2
|
|
mov x2,#255
|
|
adr x3,qOfqKey // adresse zone clé
|
|
ldr x4,[x3]
|
|
add x3,x3,x4
|
|
mov x4,#0
|
|
bl XLookupString // recup touche dans buffer
|
|
cmp x0,#1 // touche caractères ?
|
|
bne 6f
|
|
|
|
adr x0,qOfsBuffer // adresse du buffer
|
|
ldr x2,[x0]
|
|
add x0,x0,x2
|
|
ldrb w0,[x0] // charge le 1er caractère du buffer
|
|
cmp w0,#0x71 // caractere q ?
|
|
beq 7f // oui -> fin
|
|
b 6f
|
|
5:
|
|
/************************************/
|
|
/* clic mouse button */
|
|
/************************************/
|
|
cmp x0,ButtonPress // clic mouse buton
|
|
bne 51f
|
|
adr x0,qOfstEvent
|
|
ldr x5,[x0]
|
|
add x0,x0,x5
|
|
ldr w1,[x0,#+64] // position X mouse clic
|
|
ldr w2,[x0,#+68] // position Y
|
|
mov x0,x1
|
|
mov x0,x2
|
|
cmp x1,#50 // test if position clic is on the screen string approx.
|
|
blt 6f
|
|
cmp x1,#150
|
|
bgt 6f
|
|
cmp x2,#80
|
|
blt 6f
|
|
cmp x2,#105
|
|
bgt 6f
|
|
adr x1,qOfqSens // load direction
|
|
ldr x2,[x1]
|
|
add x1,x1,x2
|
|
ldr x2,[x1]
|
|
cmp x2,#0 // direction inversion
|
|
cset x2,eq
|
|
str x2,[x1]
|
|
b 6f
|
|
51:
|
|
cmp x0,#ClientMessage // code for close window within error
|
|
bne 6f
|
|
adr x0,qOfstEvent
|
|
ldr x5,[x0]
|
|
add x0,x0,x5
|
|
ldr x1,[x0,#+56] // code message address
|
|
adr x2,qOfwmDeleteMessage // equal code window créate ???
|
|
ldr x5,[x2]
|
|
add x2,x2,x5
|
|
ldr x2,[x2]
|
|
cmp x1,x2
|
|
beq 7f // yes -> end window
|
|
6:
|
|
b 3b // else events loop
|
|
|
|
7: // end program
|
|
mov x0,x28 // display address
|
|
mov x1,x24
|
|
bl XFreeGC // liberation GC1
|
|
mov x0,x28 // display address
|
|
mov x1,x26
|
|
bl XFreeGC // liberation GC2
|
|
|
|
mov x0,x28 // display address
|
|
mov x1,x27 // window ident
|
|
bl XDestroyWindow
|
|
|
|
mov x0,x28 // display address
|
|
bl XCloseDisplay // connexion X11Server Close
|
|
|
|
adr x0,qOfszMessFinPgm
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
b 100f
|
|
97:
|
|
adr x0,qOfszMessErreurX11 // X11 error
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
b 100f
|
|
98: // erreur creation fenêtre mais ne sert peut être à rien car erreur directe X11
|
|
adr x0,qOfszMessErrfen
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
b 100f
|
|
99: // erreur car pas de serveur X
|
|
adr x0,qOfszMessErreur
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
b 100f
|
|
|
|
|
|
100: // fin standard du programme
|
|
mov x0,0 // code retour
|
|
mov x8,EXIT // system call "Exit"
|
|
svc #0
|
|
qOfszMessDebutPgm: .quad szMessDebutPgm - .
|
|
qOfszMessFinPgm: .quad szMessFinPgm - .
|
|
qOfszRetourLigne: .quad szRetourLigne - .
|
|
qOfqDisplay: .quad qDisplay - .
|
|
qGris: .quad 0xF0F0F0F0
|
|
qGris1: .quad 0xFFA0A0A0
|
|
qOfszMessErreur: .quad szMessErreur - .
|
|
qOfszMessErrfen: .quad szMessErrfen - .
|
|
qOfszMessErreurX11: .quad szMessErreurX11 - .
|
|
qOfwmDeleteMessage: .quad wmDeleteMessage - .
|
|
qOfszLibDW: .quad szLibDW - .
|
|
qOfszTitreFenRed: .quad szTitreFenRed - .
|
|
qOfszWindowName: .quad szWindowName - .
|
|
qOfstEvent: .quad stEvent - .
|
|
qOfqEcran: .quad qEcran - .
|
|
qOfsBuffer: .quad sBuffer - .
|
|
qOfsbuffer1: .quad sbuffer1 - .
|
|
qOfqKey: .quad qKey - .
|
|
qSaisieMask: .quad StructureNotifyMask|ExposureMask|KeyPressMask|ButtonPressMask
|
|
qOfszTexte1: .quad szTexte1 - .
|
|
|
|
/***********************************************************/
|
|
/* Context Graphic création ***/
|
|
/***********************************************************/
|
|
/* x0 Display */
|
|
/* x1 window */
|
|
/* CAUTION : not standard use registers : return ident GC in x24 and x26 !! */
|
|
creationGC:
|
|
stp x20,lr,[sp,-16]! // save registres
|
|
stp x21,x22,[sp,-16]! // save registres
|
|
mov x20,x0
|
|
mov x21,x1
|
|
// Context Graphic création
|
|
adr x3,qOfstXGCValues2 // green color in foreground
|
|
ldr x5,[x3]
|
|
add x3,x3,x5 // this parameter is used by XcreateGC
|
|
str x4,[x3,#120] // store ident font in offset 120
|
|
mov x0,x20 // display address
|
|
mov x1,x21 // window ident
|
|
mov x2,#GCForeground // green color in foreground and font
|
|
bl XCreateGC
|
|
cmp x0,#0
|
|
beq 99f // création not OK
|
|
adr x1,qOfptGC1 // store ident graphic context
|
|
ldr x2,[x1]
|
|
add x1,x1,x2
|
|
str x0,[x1]
|
|
mov x26,x0
|
|
// création contexte 2
|
|
adr x3,qOfstXGCValues // gris1 color in foreground
|
|
ldr x5,[x3]
|
|
add x3,x3,x5 // this parameter is used by XcreateGC
|
|
mov x0,x20 // display address
|
|
mov x1,x21 // window ident
|
|
mov x2,#GCForeground // gris1 foreground
|
|
bl XCreateGC
|
|
cmp x0,#0
|
|
beq 99f // création not OK
|
|
mov x24,x0
|
|
|
|
b 100f
|
|
|
|
99: // erreur création GC
|
|
adr x0,qOfszMessErreurGC
|
|
ldr x1,[x0]
|
|
add x0,x0,x1
|
|
bl affichageMess
|
|
mov x0,#0
|
|
100:
|
|
ldp x21,x22,[sp],16 // restaur des 2 registres
|
|
ldp x20,lr,[sp],16 // restaur des 2 registres
|
|
ret // retour adresse lr x30
|
|
qGcmask1: .quad GCForeground|GCBackground
|
|
qOfszMessErreurGC: .quad szMessErrGc - .
|
|
qOfptGC1: .quad ptGC1 - .
|
|
qOfstXGCValues: .quad stXGCValues - .
|
|
qOfstXGCValues1: .quad stXGCValues1 - .
|
|
qOfstXGCValues2: .quad stXGCValues2 - .
|
|
/******************************************************************/
|
|
/* animate letters */
|
|
/******************************************************************/
|
|
/* x0 contains display address */
|
|
/* x1 window ident */
|
|
/* x2 graphic context */
|
|
/* x3 string address */
|
|
animate:
|
|
stp x20,lr,[sp,-16]! // save registres
|
|
stp x21,x22,[sp,-16]! // save registres
|
|
mov x20,x3 // save string address
|
|
mov x21,x0 // save display
|
|
mov x22,x1 // save window
|
|
mov x23,x2 // save GC
|
|
mov x0,x2
|
|
// erase text in the windows
|
|
mov x0,x21 // display address
|
|
mov x1,x22 // window ident
|
|
mov x2,x24 // graphic context
|
|
mov x3,#50 // position x
|
|
mov x4,#100 // position Y
|
|
mov x5,x20 // string address
|
|
mov x6,#LGTEXTE1 - 1 // string lenght
|
|
bl XDrawString
|
|
|
|
mov x0,#LGTEXTE1 -2 // string length
|
|
adr x1,qOfqSens // load direction
|
|
ldr x2,[x1]
|
|
add x1,x1,x2
|
|
ldr x2,[x1]
|
|
cmp x2,#0 // test direction
|
|
bne 2f
|
|
|
|
ldrb w9,[x20,x0] // last character
|
|
sub x1,x0,#1
|
|
1: // loop to move character one position
|
|
ldrb w2,[x20,x1]
|
|
strb w2,[x20,x0]
|
|
sub x0,x0,#1
|
|
subs x1,x1,#1
|
|
bge 1b
|
|
add x1,x1,#1
|
|
strb w9,[x20,x1] // last character -> first character
|
|
b 4f
|
|
2:
|
|
ldrb w9,[x20] // first character
|
|
mov x1,#1
|
|
sub x2,x1,#1
|
|
3: // loop to move character
|
|
ldrb w3,[x20,x1]
|
|
strb w3,[x20,x2]
|
|
add x2,x2,#1
|
|
add x1,x1,#1
|
|
cmp x1,x0
|
|
ble 3b
|
|
strb w9,[x20,x2] // first character -> last character
|
|
|
|
|
|
4:
|
|
// display text in the windows
|
|
mov x0,x21 // display address
|
|
mov x1,x22 // window ident
|
|
mov x2,x23 // graphic context
|
|
mov x3,#50 // position x
|
|
mov x4,#100 // position Y
|
|
mov x5,x20 // string address
|
|
mov x6,#LGTEXTE1 - 1 // string lenght
|
|
bl XDrawString
|
|
mov x0,#20 // timeout 5s approx.
|
|
bl delay
|
|
|
|
100:
|
|
ldp x21,x22,[sp],16 // restaur des 2 registres
|
|
ldp x20,lr,[sp],16 // restaur des 2 registres
|
|
ret // retour adresse lr x30
|
|
qOfqSens: .quad qSens - .
|
|
/******************************************************************/
|
|
/* timeout */
|
|
/******************************************************************/
|
|
/* x0 contains delay */
|
|
delay:
|
|
stp x1,lr,[sp,-16]! // save registres
|
|
ldr x1,qCst50000000
|
|
mul x0,x1,x0
|
|
1:
|
|
subs x0,x0,#1
|
|
bge 1b
|
|
|
|
ldp x1,lr,[sp],16 // restaur registers
|
|
ret
|
|
qCst50000000: .quad 50000000
|
|
|
|
/********************************************************/
|
|
/* File Include fonctions */
|
|
/********************************************************/
|
|
/* for this file see task include a file in language AArch64 assembly */
|
|
.include "../includeARM64.inc"
|