Forums Casio - Projets de programmation

Index du Forum | Projets de programmation | SH4 compatibility tool
Ziqumu
Hors ligne
Membre d'honneur
Niveau: Intermédiaire
Points: 2911
Défis: 9
Message
Posté le 13/07/2013 21:00

SH4 compatibility tool :

Certains l'on vu, je bosse depuis quelques jours sur un moyen de rendre compatible les addin pour les calculatrices SH4 (power graphic 2), sans qu'on ai besoin d'avoir les sources originales.

Nous avons actuellement connaissances de plusieurs problèmes de compatibilité des addin. Il faudra les résoudre un par un, voici l'état actuel :
- La fonction IsKeyDown de la FxLib : Ok
Détails
Problème : Actuellement la fonction IsKeyDown lit directement sur le port du clavier. Mais avec les nouveaux processeurs, les connexion du clavier aux cpu ont changé, et les ports ne sont plus les mêmes, donc on ne peut plus relire directement aux mêmes endroit.
Solution : Comme Casimo nous l'a montré, les SH4 ont un registre clavier qui peut être lut facilement. La solution est alors simplement de remplacer le code assembleur de la fonction IsKeyDown par un nouveau qui jump vers une fonction compatible que j'ajoute à la fin du fichier.(il suffit juste de modifier l'entete, mais ce n'est pas difficile grâce à Simon Lothar et sa doc)
Donc voilà le code qui va remplacer la fonction IsKeyDown. J'ai la flemme de traduire les commentaires, donc si vous ne comprenez pas, demandez

_IsKeyUpReplacement ; put this at offset 0xc of the IsKeyUp function. (the first two byte replaced : 63f0) THe length of the IsKeyUp function is 0x4c
    ;before : there is call of _KeyCodeConvert that put an array of two byte that respectivly contain the col and the line in the stack
    mov r15,r4 ; first param of my _GetKeyState function
    mov #2,r5 ; set slowmode of my _GetKeyState function
    mov.l GetKeyStateAddress2,r0
    jsr @r0 ;call _GetKeyState
    nop
    nop
    ;after _GetKeyState
    not r0,r0
    and #1,r0
    add #4,r15
    lds.l @r15+,pr
    rts
    nop
GetKeyStateAddress2:
    .data.l h'00301234 ; addres of my compatible _GetKeyState function : the set this address manually after compilation

ma fonction compatible _GetKeyState
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;
}

- La fonction IsKeyUp de la FxLib : ok
Details
Problème : 2 grosse mais mauvaises surprises !
La première c'est que cette fonctione ne marche pas dutout pareil que IsKeyDown. Elle utilise le syscall 0x24C appelé "Chattering" dans la fxLib.
Le prototype semble être
int Chattering(unsigned char* coord);
avec dans coord un tableau de deux char, dans le premier la collonne de la touche et dans la seconde la ligne. The syscall retourne 1 quand une touche est pressé.
Seconde suprise : Les syscall sont écris dans l'OS, donc quand casio met à jour son OS, généralement ils mettent à jour les syscalls pour qu'ils fonctionnent de nouveau. Mais là ce n'est pas le cas, apparemement ils l'ont volontairement désactivé. (s'ils l'avaient juste oublié elle ne retournerais pas 0 sur les SH4 mais crasherais tout simplement)
Solution : Bref, j'ai utilisé la même solution que pour IsKeyDown, sauf que j'ai foutu un "not" à la fin.
_IsKeyUpReplacement ; put this at offset 0xc of the IsKeyUp function. (the first two byte replaced : 63f0) THe length of the IsKeyUp function is 0x4c
    ;before : there is call of _KeyCodeConvert that put an array of two byte that respectivly contain the col and the line in the stack
    mov r15,r4 ; first param of my _GetKeyState function
    mov #2,r5 ; set slowmode of my _GetKeyState function
    mov.l GetKeyStateAddress2,r0
    jsr @r0 ;call _GetKeyState
    nop
    nop
    ;after _GetKeyState
    not r0,r0
    and #1,r0
    add #4,r15
    lds.l @r15+,pr
    rts
    nop
GetKeyStateAddress2:
    .data.l h'00301234 ; addres of my compatible _GetKeyState function : the set this address manually after compilation

- La fonction KeyDown utilisé par plusieurs addins : ok
details
Problème : Même problème que pour IsKeyDown, le port du clavier change donc c'est la merde. Ici pour identifier la fonction dans le fichier compilé, c'est un peu plus compliqué car le code n'est pas précompilé comme dans la fxlib et peut donc varier. J'ai trouvé deux formes de la fonction KeyDown. L'une lorsque l'offset de la première ligne de la fonction est divisible par 4 et l'autre lorsque que modulo 4 elle est egal à 2. J'explique cela par le fait qu'il y a certaines instructions qui ne fonctionnent pas correctement lorsque la ligne est divisible par 4 ou non : par exemple
mov.l @(h'4,pc),r0
parce qu'il peut lire un longword(4byte) qu'à un offset divisible par 4 et que le nombre en paramètre doit être un multiple de 4. Ca explique la différence.
Solution : Donc j'ai remplacé la fonction KeyDown trouvé par :
_KeyDownReplacement ; put this at beginning of the KeyDown function. (the first four byte replaced : 2FE6634C) THe length of the KeyDown function is 0x100
    ;before : keycode in r4 ; keycode=col<<4 + row
    sts.l pr,@-r15
    mov.l r1,@-r15
    mov.l r5,@-r15
    ; add #-2,r15 ;r15 need to always contain a number divisible by 4 (because when we put a longword of 4byte in the stack, we can only put it on adress multiple of 4)
    ;get the col
    mov #-4,r0
    mov r4,r1
    shld r0,r1
    ;get the row
    mov r4,r0
    and #h'f,r0
    ; mov.b r0,@-r15
    ; mov.b r1,@-r15
    ;prepartion of the array content
    shll8 r1
    add r0,r1
    shll16 r1
    mov.l r1,@-r15
    ;prepare _GetKeyState call
    mov r15,r4 ; get array address
    mov #3,r5 ; set slowmode of _GetKeyState function
    mov.l GetKeyStateAddress3,r0
    jsr @r0 ;call _GetKeyState
    nop
    ;after _GetKeyState
    add #4,r15
    mov.l @r15+,r5
    mov.l @r15+,r1
    lds.l @r15+,pr
    rts
    nop
GetKeyStateAddress3:
    .data.l h'00301234 ; addres of my compatible _GetKeyState function : the set this address manually after compilation

- Un problème d'appel de syscall, qui cause notamment l'incompatibilités de la monochromeLib : ok
details
Problème : Dans la methode utilisé par la monochrome lib :
static int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
static int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
char* ML_vram_adress()
{
    return (char*)((*SysCall)(0, 0, 0, 0, 309));
}

Le tableau SysCallCode est écris dans la mémoire (à l'adresse > 0x0810000, je ne sais pas quelle est cette mémoire, la seule chose que je sais, c'est que les addresse vers celle-ci sont écrite en dur dans le fichier et donc par conséquence elle est vide lors du chargement de l'addin). Quand ce tableau est écris en mémoire; il jump ensuite dessus (le contenu de ce tableau est un code binaire qui permet de lancer les syscall). Mais apparemment, sur les calculatrice SH4, on peut toujours lire et écrire dans cette mémoire mais on ne peut plus l'éxécuter et c'est pourquoi il plante et que l'addresse de PC à ce moment là est du style 0x0810000. Une solution simple est de ne pas copier ce tableau dans cette mémoire en le mettant en tant que constante. Ainsi, le tableau sera lu directement dans le fichier (enfin le fichier qui est chargé en mémoire) et cette partie est évidement exécutable donc il ne va pas planter.
static const int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
static int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
char* ML_vram_adress()
{
    return (char*)((*SysCall)(0, 0, 0, 0, 309));
}

Et ça fonctionne bien
Solution : Le code ci-dessus ne fonctionne pas pour nous car on ne peux pas modifier le C sans les sources.
Un autre problem est qu'il y a différents codes pour fonction d'appel de syscall car ca dépend des paramètres (ça change quand c'est une constante, une variable, un pointer..)
Voilà un code qui peut être généré.

mov.l @(H'114,pc),r3 ;//It get the address where is writed the address to the array, here it's 0x08100014
mov.l @(H'10c,pc),r2 ;//It get the syscall number, here it's 0x135
mov.l @r3,r0 ;//It get the address to the array, here it's 0x08100008
jsr @r0 ;//Jump to the array
mov.l r2,@-r15 ;//This is executed just before to jump : it put the syscall number in the stack

Pour régler ce problème je met ce code à la fin du fichier.

_SyscallFix
    mov.l #h'80010070,r2 ;//the syscall table (where we jump to execute a syscall)
    jmp @r2 ;//Jump to the syscall table
    mov.l @r15,r0 ;//Just before to jump, put the value in the stack to the register r0 (the value in the stack is the syscall number)

Et dans notre code original, je le modifie un peu :

mov.l @(H'114,pc),r3 ;// I change the value pointed to be the address of my function SyscallFix (added at the end of the file)
mov.l @(H'10c,pc),r2 ;
mov.l r3,r0 ;//change to put the address get at the first line in r0
jsr @r0 ;//Jump to the my added code
mov.l r2,@-r15 ;

Et ça marche bien. Cependant la partie la plus dure est de trouve le code à changer, mais toutes les lignes que je vous ai donné sont des lignes qui sont toujorus là, parfois séparé par d'autres instructions, mais elles sont toujours là et c'est comme ça qu'on peux le repérer.


Donc tout ce que je voulais faire est fini, mais malheureusement tous les addins ne sont pas compatible, il y a d'autres bug. Je pense qu'il y a un peu plus de la moitié des addin incompatible qui sont maintenant compatible.
La difficulté est de trouver quel est le problème en fait car on a pas d’émulateur SH4 pour voir ce qu'il se passe réellement.

Je garde la calculatrice SH4 jusqu'à la fin de la semaine, donc j’essaierais de régler quelques problèmes cette semaines, mais après je part sur d'autres projets.
Mais pour l'instant, dites moi s'il y a des addins incompatibles, j’essaierais de voir ce que je peux faire. Voilà un début de liste
Liste des incompatibilités
- Dead Labs - come back to the main menu after the introduction
- Doodle jump - Reboot - maybe cause of the grayscale
- MarioLandCE - white screen after introduction (where the grayscale begin)


SH4 compatibility tool v1.01


Faites attention ! Cet outil, peut éventuellement se révéler dangereux pour votre calculatrice. En effet une minuscule erreur pourrait par exemple empêcher de faire démarrer votre calculatrice. Je met donc cet utilitaire à votre disposition, cependant c'est à vos risques et périls que vous l'utilisez et ni moi, ni Planet-Casio ne seront responsable en cas de dégât !

Comme preuve de son fonctionnement, je vous propose de découvrir une légende sur calculatrices casio, j'ai nommé
Wolfenstein 3D - Version SH4


Merci à :
- Casimo pour ses premiers codes de compatibilité SH4
- Simon Lothar et Andreas Bertheussen pour leur documentation et leurs syscall
- Kristaba pour ce topic
- Alphacreator et Maliafo pour avoir tester les premiers programmes de test SH4
- Ayfer-Marie pour le prêt de sa calculatrice (qui d'après ce qu'elle m'a dit s’appel Reviens)

English topic

Fichier joint



Lephenixnoir
Hors ligne
Administrateur
Niveau: Confirmé
Points: 9595
Défis: 130
Message
Dernier message de la page précédente :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.
----------------------------------
La sagesse est la prunelle de tes yeux, et la gloire l’enveloppe de ton cœur.



Pages: Précédente | 1, 2, 3

Matt36230
Hors ligne
Membre
Niveau: Intermédiaire
Points: 1853
Défis: 0
Message
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 ?
----------------------------------
Lephenixnoir
Hors ligne
Administrateur
Niveau: Confirmé
Points: 9595
Défis: 130
Message
Citer : Posté le 31/01/2016 16:26 | #
As-tu essayé de tout recompiler ?
----------------------------------
La sagesse est la prunelle de tes yeux, et la gloire l’enveloppe de ton cœur.
Eltoredo
Hors ligne
Modérateur
Niveau: Intermédiaire
Points: 4186
Défis: 35
Message
Citer : Posté le 31/01/2016 16:27 | #
Souvent, le SH4 ne suffit pas, j'en ai fait les frais :/
----------------------------------
La procrastination est une vertu. (voir ma description pour comprendre mon raisonnement)
Matt36230
Hors ligne
Membre
Niveau: Intermédiaire
Points: 1853
Défis: 0
Message
Citer : Posté le 31/01/2016 16:35 | #
Oui j'ai essayé
----------------------------------
Lephenixnoir
Hors ligne
Administrateur
Niveau: Confirmé
Points: 9595
Défis: 130
Message
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 ?
----------------------------------
La sagesse est la prunelle de tes yeux, et la gloire l’enveloppe de ton cœur.
Matt36230
Hors ligne
Membre
Niveau: Intermédiaire
Points: 1853
Défis: 0
Message
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
----------------------------------
Hackcell
Hors ligne
Membre
Niveau: Aucun
Points: 450
Défis: 3
Message
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?
----------------------------------
Envie de programmer de super jeux, mais vous manquez de temps, de motivation, de connaissance ?
Testez le C-Engine de Fife86
Intelligide
Hors ligne
Membre de CreativeCalc
Niveau: Vétéran
Points: 2490
Défis: 5
Message
Citer : Posté le 07/04/2016 08:36 | #
Il cherche certaines séquences dans le code compilé et les remplace
----------------------------------
Lephenixnoir
Hors ligne
Administrateur
Niveau: Confirmé
Points: 9595
Défis: 130
Message
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
----------------------------------
La sagesse est la prunelle de tes yeux, et la gloire l’enveloppe de ton cœur.
Hackcell
Hors ligne
Membre
Niveau: Aucun
Points: 450
Défis: 3
Message
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.
----------------------------------
Envie de programmer de super jeux, mais vous manquez de temps, de motivation, de connaissance ?
Testez le C-Engine de Fife86

Pages: Précédente | 1, 2, 3

Index du Forum | Projets de programmation | SH4 compatibility tool
Publicité et partenaires
Casio Education
Casio éducation

TI-Planet
Casiopeia
Casiopeia
CasioFan, la communauté ClassPad
CasioFan
CodeWalrus
CodeWalrus

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2015 | Il y a 65 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Rugby Manager | Jeu de basket | Jeu de handball | Jeu de tennis | Nova Raider | Réparation téléphone | Soccer Rush | Tasty Tale

Planète Casio est un site communautaire indépendant, géré bénévolement et n'est donc pas affilié à Casio | Toute reproduction de Planète Casio, même partielle, est interdite
Les fichiers, programmes et autres publications présents sur Planète Casio restent la propriété de leurs auteurs respectifs et peuvent être soumis à des licences ou des copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd