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 04/11/2014 21:26 | #
L'écran de l'émulateur ne clignoterait jamais si tu n'effaçais que la VRAM x)
Ben sinon, je me suis fais prendre de vitesse, mais tant mieux si tu as réussi à résoudre ton problème.
Citer : Posté le 31/01/2016 15:53 | # | Fichier joint
Après avoir mis mon programme, il m'affiche ça :
Error 2 : we found more than one KeyDown function !
J'ai vérifié et je n'en ai pas plus de un
Quelqu'un saurait pourquoi s'il-vous-plait ?
Un beat them all pour les CPC 19
Un jeu de Tank multijoueur en version graphique
Un jeu de boxe rigolo
Le moteur de combat épique d'un RPG
soccer physics : Un jeu de foot totalement wtf !
Survie 1 & 2 te laisseras-tu attraper par la méchante IA ?
Séquestrez les tous avec Catch'em all !
Joué à la calcultarice et pécher ? Facile !
Battle un système de combat dément !!
Débombe pas tout à fait un démineur
Mon mario pour le concours des 10 ans de PC
Casio jump un doodle jump pas comme les autres !
Rush four your life : tu cours ou tu meurs
Cookie clicker ! More cookies MOOORE !
Move et esquive : bouge pour esquiver les ennemis !
Guitar Hero !! Let's rock !
INVASION : Au secours on se fait envahir !
Un devine nombre entièrement customisable (mon 1er jeu)
Un outil pour dessiner des sprites en super drawstat et qui vous le compile pour vous donner un code utilisable dans vos programmes
Un super programme de dessin bourré de trucs funcs
Sortir une version finale de Tankasio
Bien m'améliorer en C parce que pour l'instant c'est pas jojo
Une ou plusieurs idées qui mûrissent petit à petit
Citer : Posté le 31/01/2016 16:26 | #
As-tu essayé de tout recompiler ?
Citer : Posté le 31/01/2016 16:27 | #
Souvent, le SH4 ne suffit pas, j'en ai fait les frais :/
Citer : Posté le 31/01/2016 16:35 | #
Oui j'ai essayé
Un beat them all pour les CPC 19
Un jeu de Tank multijoueur en version graphique
Un jeu de boxe rigolo
Le moteur de combat épique d'un RPG
soccer physics : Un jeu de foot totalement wtf !
Survie 1 & 2 te laisseras-tu attraper par la méchante IA ?
Séquestrez les tous avec Catch'em all !
Joué à la calcultarice et pécher ? Facile !
Battle un système de combat dément !!
Débombe pas tout à fait un démineur
Mon mario pour le concours des 10 ans de PC
Casio jump un doodle jump pas comme les autres !
Rush four your life : tu cours ou tu meurs
Cookie clicker ! More cookies MOOORE !
Move et esquive : bouge pour esquiver les ennemis !
Guitar Hero !! Let's rock !
INVASION : Au secours on se fait envahir !
Un devine nombre entièrement customisable (mon 1er jeu)
Un outil pour dessiner des sprites en super drawstat et qui vous le compile pour vous donner un code utilisable dans vos programmes
Un super programme de dessin bourré de trucs funcs
Sortir une version finale de Tankasio
Bien m'améliorer en C parce que pour l'instant c'est pas jojo
Une ou plusieurs idées qui mûrissent petit à petit
Citer : Posté le 31/01/2016 16:58 | #
As-tu essayé de supprimer le dossier Debug avant de recompiler ? C'est bizarre, je n'ai vu de fonction KeyDown qu'à un endroit. Tu n'as pas ajouté le fichier en double ou quelque chose du genre ?
Citer : Posté le 31/01/2016 17:01 | #
Oui, il n'est bien qu'à un endroit. Non
Ajouté le 31/01/2016 à 17:34 :
Je vois d'ou vient le problème c'est bon. Au début de usefull.c, il y a à peu près le même code que mon pote m'avais passé pour rendre compatible SH4. Le problème c'est que je n'ose pas toucher à usefull parce que sinon je vais faire n'importe quoi et que si je supprime le code de mon pote les valeurs des touches ne sont plus du tout les mêmes
Un beat them all pour les CPC 19
Un jeu de Tank multijoueur en version graphique
Un jeu de boxe rigolo
Le moteur de combat épique d'un RPG
soccer physics : Un jeu de foot totalement wtf !
Survie 1 & 2 te laisseras-tu attraper par la méchante IA ?
Séquestrez les tous avec Catch'em all !
Joué à la calcultarice et pécher ? Facile !
Battle un système de combat dément !!
Débombe pas tout à fait un démineur
Mon mario pour le concours des 10 ans de PC
Casio jump un doodle jump pas comme les autres !
Rush four your life : tu cours ou tu meurs
Cookie clicker ! More cookies MOOORE !
Move et esquive : bouge pour esquiver les ennemis !
Guitar Hero !! Let's rock !
INVASION : Au secours on se fait envahir !
Un devine nombre entièrement customisable (mon 1er jeu)
Un outil pour dessiner des sprites en super drawstat et qui vous le compile pour vous donner un code utilisable dans vos programmes
Un super programme de dessin bourré de trucs funcs
Sortir une version finale de Tankasio
Bien m'améliorer en C parce que pour l'instant c'est pas jojo
Une ou plusieurs idées qui mûrissent petit à petit
Citer : Posté le 06/04/2016 22:49 | #
A propos de compatibility tools, comment il fonctione sans les codes sources?
Il localise les patern du code compilé qui pose probleme et les remplace par ce qu'il faut?
Citer : Posté le 07/04/2016 08:36 | #
Il cherche certaines séquences dans le code compilé et les remplace
Citer : Posté le 07/04/2016 13:47 | #
En fait il repère les appels aux fonctions problématiques et les remplace par des appels à des fonctions custom qu'il ajoute à la fin du fichier, pour éviter au système de faire des bêtises.
Mais si l'outil est considéré risqué, en pratique on n'a jamais eu de problème avec
Citer : Posté le 07/04/2016 14:45 | #
D'accord, c'est bon j'ai enfin compris, et je me rends compte que ça n'a pas du être simple.
Donc bravo.
Citer : Posté le 26/12/2019 12:13 | #
Je sais pas si cet outil est encore utile dernièrement, mais au cas où certains sont intéressé, j'ai publié le code source sur le gitea de Planète Casio ainsi qu'une documentation amélioré
(Miroir Github)
Bonnes fêtes de fin d'année !