Cette fonction est compatible avec les cpu et peut attendre pour émuler les ancienne fonction qui sont lentes. Cette fonction est assez rapide (enfin pas aussi fast que KeyDown, mais KeyDown n'est pas compatible SH4), donc je pense que si je l'optimise un peu cette fonction pourrait être bien pratique pour les nouveaux programmes. Mais bon je débute en assembleur, donc bon on peut sans doute améliorer.
;param 1 (in r4) : Adress of an array of two unsigned char, with in the first cell the col, and in the second the row
;param 2 (in r5) : slowMode : this determine the time this function will wait to emulate the olds functions
; -n : number of loop
; 0 : fatest as possible
; 1 : = duration of IsKeyDown function
; 2 : = duration of IsKeyUp function
; 3 : = duration of KeyDown function
;return (in r0) 1 if the key is pressed.
_GetKeyState
;First put actual value in the stack
sts.l pr,@-r15
mov.l r1,@-r15
mov.l r2,@-r15
mov.l r3,@-r15
mov.l r6,@-r15
mov.l r7,@-r15
mov.l r8,@-r15
mov.l r9,@-r15
mov r4,r8 ; first param
mov r5,r9 ; second param
;check the os version with the syscall 0x0015 | if I use only 1 byte for chars, and 2 for short, it crash on all calc but not on emulator. But these type are valid because the syscall only edit the correct number of byte.
add #-4,r15 ; main version : unsigned char
mov r15,r4
add #-4,r15 ; minor version : unsigned char
mov r15,r5
add #-4,r15 ; release : unsigned short
mov r15,r6
add #-4,r15 ; build : unsigned short
mov r15,r7
;call syscall
mov.l #h'80010070,r2
jsr @r2
mov #h'15,r0
;put os version into r6
add #8,r15
mov.b @r15,r6 ; minor version
add #4,r15
mov.b @r15,r0 ; main version
add #4,r15
shll8 r0 ; r0 = r0<<8
add r0,r6
;reserved registers :
;r9 second param
;r6 OS version
; read and checks coords
mov.b @r8,r7 ; r7 = Key's column
mov.b @(1,r8),r0
mov r0,r8 ; r8 = Key's row
;verify the row value : 0 ≤ row ≤ 9
mov #0, r0
cmp/gt r8,r0 ; if r0 > r8 ⇒ if 0 > row
bt NegativeEnd
mov #9,r1
cmp/gt r1,r8 ; if r8 > r1 ⇒ if row > 9
bt NegativeEnd
;verify the column value : 0 ≤ row ≤ 6
cmp/gt r7,r0 ; if r0 > r7 ⇒ if 0 > column
bt NegativeEnd
mov #6,r1
cmp/gt r1,r7 ; if r7 > r1 ⇒ if column > 6
bt NegativeEnd
;check if os is > 2.02
mov.w #h'0202,r0
cmp/ge r0,r6 ; r0 ≤ r6
bt SH4
;reserved registers :
;r9 second param
;r8 Key's row
;r7 Key's col
;SH3 part
;r6 = smask = 0x0003 << (( row %8)*2);
mov r8,r0 ; row->r0
and #7,r0 ; %8
add r0,r0 ; *2
mov #3,r6
shld r0,r6 ; 3<<
;r5 = cmask = ~( 1 << ( row %8) );
mov r8,r0 ; row->r0
and #7,r0 ; %8
mov #1,r5
shld r0,r5 ; 1<<
not r5,r5 ; ~
;reserved registers :
;r9 second param
;r8 Key's row
;r7 Key's col
;r6 smask
;r5 cmask
;Preparation of the gbr register
mov.l #h'A4000100,r0
ldc r0,gbr
;RowCond : if(row <8)
mov #8,r0
cmp/gt r8,r0 ; if r0>r8 ; row>=8
bf rowCond_Else
;rowCond_begin
;*PORTB_CTRL = 0xAAAA ^ smask;
mov r6,r0
mov.w #h'AAAA,r1
xor r1,r0
mov.w r0,@(h'02,gbr)
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x00AA;
mov.w @(h'18,gbr),r0 ; *PORTM_CTRL->r0
mov.w #h'FF00,r1
and r1,r0 ; *PORTM_CTRL & 0xFF00
or #h'AA,r0 ; | 0x00AA;
mov.w r0,@(h'18,gbr)
;delay()
bsr delay
mov #-10,r4
;*PORTB = cmask;
mov r5,r0
mov.b r0,@(h'22,gbr) ;PORTB = cmask
;*PORTM = (*PORTM & 0xF0 ) | 0x0F;
mov.b @(h'38,gbr),r0 ; *PORTM->r0
and #h'F0,r0 ; *PORTM & 0xF0
or #h'0F,r0 ; | 0x0F;
mov.b r0,@(h'38,gbr)
bra rowCond_End
nop
rowCond_Else:
; *PORTB_CTRL = 0xAAAA;
mov.w #h'AAAA,r0
mov.w r0,@(h'02,gbr)
; *PORTM_CTRL = ((*PORTM_CTRL & 0xFF00 ) | 0x00AA) ^ smask;
mov.w @(h'18,gbr),r0
mov.w #h'FF00,r1
and r1,r0 ; *PORTM_CTRL & 0xFF00
or #h'AA,r0 ; | 0x00AA;
xor r6,r0 ; ^ smask;
mov.b r0,@(h'18,gbr)
;delay()
bsr delay
mov #-10,r4 ;In the begin this was 5, but as the delay function is faster, i need to put more
;*PORTB = 0xFF;
mov.b #h'ff,r0
mov.b r0,@(h'22,gbr) ;PORTB = 0xFF
;*PORTM = (*PORTM & 0xF0 ) | cmask;
mov.b @(h'38,gbr),r0
and #h'F0,r0 ; *PORTM & 0xF0
or r5,r0 ; | cmask;
mov.b r0,@(h'38,gbr)
rowCond_End:
;reserved registers :
;r9 second param
;r8 Key's row
;r7 Key's col
;delay()
bsr delay
mov #-10,r4
;result = (~(*PORTA))>>column & 1;
mov.b @(h'20,gbr),r0
not r0,r6 ; r6 = ~r0
neg r7,r0 ; r0 = -column
shld r0,r6 ; r6 = r6>>column
mov.b #1,r0
and r0,r6
;reserved registers :
;r9 second param
;r8 Key's row
;r7 Key's col
;r6 result
;delay()
bsr delay
mov #-10,r4
; *PORTB_CTRL = 0xAAAA;
mov.w #h'AAAA,r0
mov.w r0,@(h'02,gbr)
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x00AA;
mov.w @(h'18,gbr),r0
mov.w #h'FF00,r1
and r1,r0 ; *PORTM_CTRL & 0xFF00
or #h'AA,r0 ; | 0x00AA;
mov.w r0,@(h'18,gbr)
;delay()
bsr delay
mov #-10,r4
; *PORTB_CTRL = 0x5555;
mov.w #h'5555,r0
mov.w r0,@(h'02,gbr)
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x0055;
mov.w @(h'18,gbr),r0
mov.w #h'FF00,r1
and r1,r0 ; *PORTM_CTRL & 0xFF00
or #h'55,r0 ; | 0x0055;
mov.w r0,@(h'18,gbr)
;delay()
bsr delay
mov #-10,r4
;End of SH3 part
bra AllEnd
nop
SH4:
;Add 3 to the second param (if >0)to select the right wait time
mov #0,r0
cmp/gt r0,r9
bf negatif2ndParam
add #3,r9
negatif2ndParam:
;get the main keyboard regsiter address+1
mov.l #H'A44B0001,r1
mov r8,r0
tst #1,r0 ;if row is even T=1 else T=0
add r8,r1
bt row_even ; Jump if T=1
add #-2,r1
row_even:
mov.b @r1,r0 ; The byte that contain the row data is now in R0
mov #1,r1
shld r7,r1 ; R9 now contain 1<<col
tst r1,r0 ; if key is pressed T=0
movt r0
not r0,r0
and #h'1,r0
mov r0,r6
bra AllEnd
nop
NegativeEnd:
mov #0,r6
;reserved registers :
;r9 second param
;r8 Key's row
;r7 Key's col
;r6 result
AllEnd:
;Wait the correct time to emulate old functions
bsr delay
mov r9,r4
;put result to return register : r0
mov r6,r0
;take out data from stack
mov.l @r15+,r9
mov.l @r15+,r8
mov.l @r15+,r7
mov.l @r15+,r6
mov.l @r15+,r3
mov.l @r15+,r2
mov.l @r15+,r1
lds.l @r15+,pr
rts
nop
; delay : Wait a defined time
;param 1 (in r4) : slowMode : this determine the time this function will wait to emulate the olds functions
; -n : number of loop
; 0 : fatest as possible (equivalent to -1)
; 1 : = duration of IsKeyDown function for SH3
; 2 : = duration of IsKeyUp function for SH3
; 3 : = duration of KeyDown function for SH3
; 4 : = duration of IsKeyDown function for SH4
; 5 : = duration of IsKeyUp function for SH4
; 6 : = duration of KeyDown function for SH4
delay:
;if r4<=0 then it's the number of loop
mov #0,r0
cmp/ge r0,r4
bf LoopNumber
;Search the number of loop needed
add r4,r4 ; *2
mova loopNumbersList,r0
add r4,r4 ; *2 because there is 4 byte per number of loop (this method take less space than use "MUL.L")
add r4,r0
mov.l @r0,r1
bra target_loopBegin
nop ; this nop is added because without the loopNumbersList is not divisible per 4
loopNumbersList:
.data.l h'0001 ;fastest
.data.l h'0001 ;IsKeyDown SH3
.data.l h'0001 ;IsKeyUp SH3
.data.l h'0001 ;KeyDown SH3
.data.l h'0001 ;IsKeyDown SH4
.data.l h'0001 ;IsKeyUp SH4
.data.l h'0001 ;KeyDown SH4
LoopNumber:
neg r4,r1
;Begin : r1 contain the number of loop
target_loopBegin:
dt r1 ; decrement and test if(r1==0)
bf target_loopBegin
rts
nop
Voilà les mesures que j'ai fait pour calculer le temps que prend chaque fonction. (copier ce code dans un editeur texte pour mieux voir..)
;Loop numbers tests : Number of tick taked to execute 5000 times the function
;I made some change between and after theses test so it's possible that if you do it again, you don't find same number, but the little difference will not be really significant. Because this test is on a loop of 5000 times, and mesured in tick (I'm not sure, but I remember it's egal to 1/64 seconds) and one tick is not verry significant for human.
;--------------------------------------------------------------------------------
; |Original | SH3 | SH4 |
;--------------------------------------------------------------------------------
;IsKeyDown |0xb2 |0x17(miss 155) |0x11(miss 161) |
;IsKeyDown with 0x1000 waitloop |---- |0x17b |0x1cd | : Conclusion 0x1000 loop takes 0x164 ticks to be executed on SH3=> (1024/89) loop/ticks
| SH4=> (1024/111) loop/ticks | (I think I've make a mistake somewhere, because on my first try, number of loop was stored in Word (2byte),
| and there was (1024/89) loop/ticks for both cpu, but since I change from word to longword (4byte) and now the sh4 is slower..No idee why.
;IsKeyDown|sh3:1783|sh4:1485 |---- |0xb2 |0xb2 |
;--------------------------------------------------------------------------------
;IsKeyUp |0x1a43 |0x17(miss 6700)|0x11(miss 6706)|
;IsKeyDown|sh3:0x12D1F|sh4:0xF1A8 |---- |0x1a42 |0x1a4a |
;--------------------------------------------------------------------------------
;KeyDown |0x9 |0x11 |0xd | : As the original function is faster than the compatible, we put the slowmode at the minimum for both cpu : 1
;--------------------------------------------------------------------------------
J'ai fais les tests avec ce code
int AddIn_main(int isAppli, unsigned short OptionNum)
{
unsigned int timeBegin;
unsigned int duration;
char string[9];
int i;
while(1)
{
timeBegin = RTC_GetTicks();//RTC_GetTicks is a syscall documented in FxReverse
for(i=0;i<5000;i++)
{
key_down(K_EXE);//Change this function here
}
duration = RTC_GetTicks()-timeBegin;
intToHex(duration, string);
Bdisp_AllClr_DDVRAM();
locate(1,1);
Print((unsigned char*)string);
Bdisp_PutDisp_DD();
}
return 1;
}
void intToHex(unsigned int in, char* string)
{
string[0] = nibbleToHex((unsigned char)in>>28);
string[1] = nibbleToHex((unsigned char)(in>>24)&0xF);
string[2] = nibbleToHex((unsigned char)(in>>20)&0xF);
string[3] = nibbleToHex((unsigned char)(in>>16)&0xF);
string[4] = nibbleToHex((unsigned char)(in>>12)&0xF);
string[5] = nibbleToHex((unsigned char)(in>>8)&0xF);
string[6] = nibbleToHex((unsigned char)(in>>4)&0xF);
string[7] = nibbleToHex((unsigned char)in&0xF);
string[8] = 0;
}
char nibbleToHex(unsigned char in)
{
char out;
if(in <= 9)
out = 0x30 + (unsigned int)in;
else
{
switch(in-10)
{
case 0 : out = 0x61; break;
case 1 : out = 0x62; break;
case 2 : out = 0x63; break;
case 3 : out = 0x64; break;
case 4 : out = 0x65; break;
case 5 : out = 0x66; break;
}
}
return out;
}
Citer : Posté le 13/07/2013 21:06 | #
Je viens de remarquer que ma modification est bien plus rapide que l'ancienne fonction IsKeyDown, il faudra que je la modifie un peu pour la ralentir.
Citer : Posté le 13/07/2013 21:44 | #
Tu vas faire des heureux !
Vitesse des fonctions en Basic Casio | 7 days CPC | Casio Universal Wiki | Tutoriel Basic Casio
>>> Give me a click Brother <<< >>> Teste mon générateur de mots nouveaux <<<
>>> Random Youtube Video <<<
Citer : Posté le 14/07/2013 02:44 | #
C'est le but !
Citer : Posté le 14/07/2013 08:50 | #
Excellent
Citer : Posté le 14/07/2013 09:44 | #
C'est génial !
Calculatrices : Graph 35+ USB tweakée et Classpad 330
Suivez moi et mon humour dévastateur ici focliquéla
Citer : Posté le 23/07/2013 23:36 | #
Je part 2 semaines, et quand je revient je vois que tu as (presque) résolut les problèmes de compatibilité !
GG !
Citer : Posté le 28/07/2013 19:44 | #
Incroyable ! Alors là ! Mais si j'avais put imaginer un jour que quelqu'un arriverait à faire ça ! Je te dis juste GG C'est de l'excellent boulot
Projet de combat au tour par tour type DOFUS mais totalement orienté sur le PvP. Le projet va demander un peu de temps mais soyons patient...
Le titre (laby3D) en dit long sur son contenu : il s'agit d'un simple moteur de labyrinthe en "3D" (enfin on va dire juste un effet de profondeur ). il aura la particularité d'être aggrémenté de superbes petites animations sur les rotations d'angles de vue ! j'y bosse pas mal et j'espère bien le réussir !
Le jeu devrait sortir bientôt
Citer : Posté le 30/07/2013 15:04 | #
Décidément rien n'est impossible
Citer : Posté le 31/07/2013 00:05 | #
Update de la version 1.00, potentiellement finale, je vous laisse lire plus haut j'explique ou j'en suis
(enfin ne déroulez pas les spoiler non plus, vous risqueriez de vous perdre )
Ajouté le 01/08/2013 à 14:49 :
Mise à jour 1.01 : Correction d'un bug qui apparaissait quand un fichier avait une taille non divisible par 4.
Citer : Posté le 01/08/2013 16:19 | #
Cet outil, peut éventuellement se révéler dangereux pour votre calculatrice.
Moi c'est ça qui me fait flipper Oo' C'est quoi que tu appels une erreur? j'ai pas trop compris ça ^^'
En tout cas bravo
Projet de combat au tour par tour type DOFUS mais totalement orienté sur le PvP. Le projet va demander un peu de temps mais soyons patient...
Le titre (laby3D) en dit long sur son contenu : il s'agit d'un simple moteur de labyrinthe en "3D" (enfin on va dire juste un effet de profondeur ). il aura la particularité d'être aggrémenté de superbes petites animations sur les rotations d'angles de vue ! j'y bosse pas mal et j'espère bien le réussir !
Le jeu devrait sortir bientôt
Citer : Posté le 01/08/2013 16:28 | #
Bah imaginons j'ai fait un mauvais saut dans le code assembleur, et il saute à un endroit qui lui dit d'écrire dans la mémoire flash au niveau du système, dans ce cas là ça peut potentiellement empêcher ta calculatrice de démarrer. (c'est comme si tu modifiais le dossier Windows de ton PC) C'est peu probable et ça ne m'est jamais arrivé malgré le nombre incalculable de test que j'ai fait et qui ont planté, mais je préfère nous protéger et prévenir du risque potentiel.
Mais bon en même temps même les addins qui ne sont pas modifié par mon outil peuvent faire ce genre de chose.. Involontairement quand ça crash, et même volontairement si l'auteur en avait envie, il n'y a aucune sécurité malheureusement.
Merci
Invité
Citer : Posté le 01/08/2013 17:14 | #
Peut-tu faire Orton de PLL ?
Merci
Citer : Posté le 01/08/2013 19:27 | #
C'est bon, je l'ai posté dans les commentaires du programme.
Ajouté le 01/08/2013 à 19:28 :
(le fait que le programme est très sombre existait déjà sur les ancienne graph75)
Citer : Posté le 01/08/2013 19:49 | #
Ok merci de l'explication Ziqumu
Effectivement je n'avais jamais réellement pensé à la possibilité de nuire aux autres via un add-in plantant la calculatrice, mais en même temps... faut vraiment avoir que ça à faire de sa vie :/
enfin bref, j'espère que beaucoup de bon jeu seront enfin accessible à tous
Projet de combat au tour par tour type DOFUS mais totalement orienté sur le PvP. Le projet va demander un peu de temps mais soyons patient...
Le titre (laby3D) en dit long sur son contenu : il s'agit d'un simple moteur de labyrinthe en "3D" (enfin on va dire juste un effet de profondeur ). il aura la particularité d'être aggrémenté de superbes petites animations sur les rotations d'angles de vue ! j'y bosse pas mal et j'espère bien le réussir !
Le jeu devrait sortir bientôt
Invité
Citer : Posté le 01/08/2013 20:21 | #
Merci Ziqumu pour Orton
Citer : Posté le 02/08/2013 16:55 | #
On peut remettre le contraste comme on veut avec l'astuce Shift + flèches dans Orton.
Calculatrices : Graph 35+ USB tweakée et Classpad 330
Suivez moi et mon humour dévastateur ici focliquéla
Citer : Posté le 03/08/2013 08:21 | #
Merci Ziqumu pour ce formidable outil
@ Tsuneo : Désolé mais ton astuce ne fonctionne pas sur la version SH4 d'Orton.
Zelda de Smashmaster
Super Geek Brothers de Siapran
Pac-Man
Pac-Man Color
Meta Ball
Add-ins Jetpack Joyride et Pac-Man sur PRIZM (les 2 non commencés mais en réflexion)
A la recherche des sprites jetpack Joride si quelqu'un les a en couleur
Citer : Posté le 03/08/2013 21:11 | #
Euh, il faut retourner dans le menu, j'ai oublié de préciser. Normalement en appuyant sur Menu, après tu utilises l'astuce Shift + flèches, tu rappuies sur Menu pour rentrer dans le jeu et ça marche. Par contre je crois qu'il faut le faire à chaque niveau.
Calculatrices : Graph 35+ USB tweakée et Classpad 330
Suivez moi et mon humour dévastateur ici focliquéla
Citer : Posté le 05/08/2013 12:41 | #
ziqmu, t'as observé des erreurs de lectures de touches dans KeyDown? Certaines combinaisons ont un comportement erratique qui provoque la lecture d'autres touches...
Citer : Posté le 05/08/2013 12:49 | #
du genre Shift + up + down => Alpha + up + down (visible dans Gravity Duck)