Page 1 of 1

[Résolu] Le désarchivage laborieux...

Unread postPosted: 21 Dec 2015, 21:09
by Epharius
Hell ô Ève Riz Beau Dit !
Cela fait maintenant une semaine que je cherche, j'ai avancé dans mes recherches mais il me manque des informations, voilà le problème (ne vous faites pas décourager par la longueur du post, il y a beaucoup d'images, de code etc...) :

Vous le savez peut-être déjà mais je suis en train de faire en sorte qu'on puisse éditer les programmes archivés grâce à PHASM. J'ai décidé pour cela de faire la chose suivante :
- Grâce à un menu hook, on désarchive quand l'user demande à éditer un programme archivé dans la liste des programmes
- On laisse l'user faire ce qu'il veut dans l'edit buffer
- quand il a fini, on réarchive le programme ni vu ni connu

Malheureusement, ce n'est pas aussi facile que je ne le croyais, et j'ai vite découvert que le simple fait de désarchiver (l'archivage marche sans problème) détruit en partie le programme unARC. voici une image du code avant et après (à noter que c'est toujours au même endroit que les caractères bizarres apparaissent, et à seulement cet endroit là pour le programme) :
bug.png
bug1.png

Donc ce désarchivage se fait au moment où l'user a sélectionné un Item dans le menu d'édition des programmes, juste avant que l'OS n'affiche soit l'edit buffer, soit "Err:Archived".

J'ai fait un taaas de recherches, pendant 1 semaine, et voici ce que j'ai pu noter :
It works :
- Si on vient d'archiver la variable, que ce soit dans le hook ou par le menu de l'OS, sans passer par :f11: ou autre
- Si on UNARC dans un endroit où il n'y a pas l'air d'y avoir un buffer d'ouvert (c-à-d dans graphe ou dans Trace)

It does not work :
- Les tokens bizarres apparaissent toujours au token environ 56.


Ce n'est qu'un résumé, et après cela j'en ai tiré une conclusion : ce problème survient car un buffer est ouvert, et qui dit buffer ouvert, dit aucune allocation mémoire possible ! Je ne suis pas sûr à 100% mais tout colle et pousse à dire que c'est à cause de ça, lisez le spoiler si vous avez le courage d'affronter des explications floues :
Show/Hide spoilerAfficher/Masquer le spoiler
on peut archiver sans problème, quand on est dans un menu qui ne nécessite pas de buffer, ça marche, les tokens bizarres apparaissent toujours au même endroit. Pourquoi au même endroit ? Parce que la RAM ne détruit pas au moment de l'archivage le programme qui était en RAM pour les performances, et le désarchivage ne fait que changer un pointeur, mais pendant ce temps là, quelque chose est allé s'installer ici, d'où aussi la nécessité de ne pas aller dans des endroits qui utilisent des buffers juste après l'archivage (Si on vient d'archiver la variable, que ce soit dans le hook ou par le menu de l'OS, sans passer par :f11: ou autre) (c'est ma théorie).

Ok tout cela peut vous être un peu flou, c'est dur de résumer 15h de recherches en 5 lignes. Mais le principal est que vous ayez compris qu'il y a beaucoup de chances que ça vienne d'un buffer ouvert qui empêche ARC_UNARC d'allouer de la mémoire dans la RAM.

Alors, on a une piste, maintenant, qu'est-ce qu'on fait ? Ben on trouve une solution ! Malheureusement, malgré mes efforts, ce fut vain. J'ai essayé de fermer un possible buffer en cours avec call _closeEditBuf et call _releaseBuffer mais toujours le même problème : des caractères bizarres apparaissent au même endroit. Vraiment incompréhensible... cela ne viendrait pas d'un buffer ? De plus, quelque chose me dérange... si on fait dans cet ordre :
  • Archiver le programme avec le menu de l'OS
  • Aller directement dans le menu qui liste les programme à éditer
  • Éditer le programme qu'on vient d'archiver
Aucun problème ! Ça marche ! Il en est de même si on archive d'une autre façon le programme, avec un programme asm par exemple... Peut-être que puisque le buffer n'est pas sollicité, il n'overwrite rien...


Bon, je pense avoir tout dit, donc voilà le code utilisé qui est censé marcher :
Code: Select all
MenuHook:
   .db 83h     ; Commun à tous les hooks
   cp 3          ; Si on est dans la sélection d'un élément dans un menu
   jr nz,quit
   ld a,(menuCurrent)   ; On verifie qu'on est bien dans le menu qui liste les programmes à éditer
   cp mProgramHome
   jr nz,quit
   ld a,(menuCurrent+1)
   cp mPrgm_Edit
   jr nz,quit

   push bc    ; BC doit revenir tel quel à la fin de l'exécution du hook
   push de    ; à DE se trouve le nom de l'item sélectionné (donc le nom du programme)
   call _ReleaseBuffer   ; On évacue le buffer en cours
   pop de
   ld hl,-9
   add hl,de
   call _mov9toop1  ; nom du programme dans OP1
   ld a,5
   ld (OP1),a
   call _chkfindsym   ; pas spécialement dur à comprendre...
   call _chkInRam
   call nz,_ARC_UNARC
   pop bc
quit:
   cp a            ; On met le flag Z à un pour dire à l'OS qu'il ne doit pas annuler l'action en cours
   ret
endHook:


À la moindre question, le moindre doute, même si vous pensez que c'est complétement con, n'hésitez pas ! Si vous avez des tests à me proposer aussi, je me ferai un plaisir d'essayer !

Re: Le désarchivage laborieux...

Unread postPosted: 21 Dec 2015, 21:48
by Hayleia
Sinon, je ne sais même pas si ça résout le problème, ça ne fait peut être que le déplacer, mais au lieu de désarchiver le programme, est-ce que t'as essayé de le lire depuis l'archive ?
Tu me diras "on peut pas l'éditer s'il reste en archive". Oui, mais si tu peux éditer un programme temporaire dans lequel tu auras recopié le contenu du programme voulu, ça passe.
Si c'est bien "allouer de la mémoire" qui pose problème, cette "solution" ne règlera rien vu que le programme temporaire devra toujours être "alloué", donc teste déjà si tu peux créer des programmes depuis le code de ton hook.

Du coup si ça marche, dans l'ordre, lorsque le hook se déclenche, l'utilisateur voulant éditer le programme AEDITER tu ferais :
  • créer un programme LOLZ (nom débile pour y faire référence ensuite) de la même taille que celui à éditer
  • recopier le programme qu'on veut éditer
  • éditer LOLZ qui du coup est désarchivé

Et en fin d'édition tu fais ça
  • supprimer AEDITER
  • renommer LOLZ en AEDITER
  • archiver

Voilà de l'Axe décompilé qui lit le premier octet de l'appvar Toaster même si elle est archivée (oui, c'est long, et en plus les labels ont des vieux noms).
Show/Hide spoilerAfficher/Masquer le spoiler
Code: Select all
.db $BB,$6D

lblStart:
ld hl,data9E10
ld de,smallEditRAM+93
call l9DAA
ld hl,(smallEditRAM+93)
ld a,(smallEditRAM+95)
call l9DE7
ld h,$00
ret

l9DAA:
push de
rst 20h
b_call _ChkFindSym
jr c,l9DE2
inc b
djnz l9DC0
ld h,b
ld l,b

l9DB6:
and $1F
jr z,l9DD9
cp $0C
jr z,l9DD9
jr l9DD7

l9DC0:
b_call $4363
ld hl,$C00C
jr nz,l9DB6
ld l,$09
add hl,de
bit 6,h
jr z,l9DD0
inc b

l9DD0:
set 6,h
b_call _LoadDEIndPaged
ld d,$C0

l9DD7:
inc de
inc de

l9DD9:
add hl,de
ex de,hl
pop hl
ld (hl),e
inc hl
ld (hl),d
inc hl
ld (hl),b
ret

l9DE2:
ld hl,$0
pop de
ret

l9DE7:
or a
jr z,l9E0B
ld c,a
in a,($06)
ld b,a
ld a,h
set 6,h
res 7,h
rlca
rlca
and $03
add a,c
out ($06),a
ld c,(hl)
inc hl
bit 7,h
jr z,l9E05
ld h,$40
inc a
out ($06),a

l9E05:
ld h,(hl)
ld l,c
ld a,b
out ($06),a
ret

l9E0B:
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ret

data9E10:
.db $15,$54,$6F,$61,$73,$74,$65,$72,$00

Re: Le désarchivage laborieux...

Unread postPosted: 21 Dec 2015, 22:06
by Epharius
Non, qui dit allocation mémoire impossible, dit impossible de créer quoique ce soit, toujours le même problème, et le plus étonnant c'est que c'est toujours à l'octet 56 que ça foire :/

Re: Le désarchivage laborieux...

Unread postPosted: 22 Dec 2015, 15:07
by Epharius
Oké, alors...

Ces 7 derniers jours furent pour moi supers importants, car ils me permirent de mieux comprendre le fonctionnement de l'OS, vraiment. Par exemple sur le moniteur, sur les buffers... mais quand je vois la simplicité de la solution, je me dis que... j'me sens con ouais :p
C'est pas simple dans le sens où il suffit d'y penser, mais simple dans le sens où y'a juste à appeler une RomCall pour résoudre le problème.

En fait, au code donné auparavant, il suffit de rajouter call _PPutAway (avec deux P) après call _ReleaseBuffer et ça marche, tout simplement. Bon, ça m'a quand même obligé à éplucher une dizaine de docs' sur le moniteur, sur les buffers, et sur les romcalls, mais ça y est :p

Bref, gout d'aphte ère nous ne.

Re: [Résolu] Le désarchivage laborieux...

Unread postPosted: 22 Dec 2015, 16:25
by Hayleia
Évidemment qu'on est contents que t'aies la solution, mais ton explication est un peu légère (en fait t'en as pas :P).
Elle fait quoi exactement cette romcall qui résout tout, et pourquoi ça résout le problème ?

Re: [Résolu] Le désarchivage laborieux...

Unread postPosted: 22 Dec 2015, 16:48
by Epharius
Attention : ce qui va suivre n'est pas clair, je ne maitrise pas vraiment le sujet :p

Bon je vais vous raconter ce que j'ai compris :
Pas grand chose.

Na plus sérieusement j'ai appris plein de choses mais pas forcement sur la solution du problème. Cette solution je l'ai trouvé dans ça :
Closing an Edit Session
To close an edit session, use CloseEditEqu. You will probably want to close the edit session as soon as you are done with it, but in any case, it needs to be closed before the app returns to the OS. If you are using GetKey while the edit buffer is open, this means you will you will need to use Put Away notification to close the edit buffer before returning to the OS.


Mais après vérification, j'avais essayé call _PutAway, et ça ne marchait pas. Donc j'ai regardé plus tard (genre 4 jours après) dans l'include et j'ai trouvé _PPutAway, surement une contraction de Program Put Away, je ne sais pas trop...

Bref, ça c'est pour la petite histoire. Pour les explications : le moniteur, appelé avec call _Mon est un peu l'OS visible de la calculatrice. C'est lui qui affiche les menus, qui exécute les applications etc... Et quand on exécute un programme assembleur, il doit laisser la main au programme et la reprendre, ou un truc du genre. Sauf que les hooks, eh bien ils restent sous son contrôle, et donc doivent quitter le moniteur avec call _PPutAway. Mais après, ne me demandez pas quel lien il y a avec "If you are using GetKey while the edit buffer is open". J'ai bien une idée mais bon, que des spéculations : peut-être que qui dit buffer avec un getkey, dit moniteur, parce que le programmeur ne va pas s'amuser à reproduire tous les menus etc...
Par contre, je ne sais pas le lien entre l'impossibilité d'UNARC et l'ouverture du moniteur...

Enfin, faites-en ce que tu voulez, j'en sais pas grand chose sur le moniteur !