26Fermer28
deephLe 28/02/2013 à 20:54
J'ai un début de gestion des programmes TI-Basic archivés (grâce à la source de noshell) : on crée un programme temporaire avec un nom unique, puis on y copie les données archivées avant de l'exécuter, mais je ne sais pas pourquoi ça bug encore (le programme temporaire semble bien créé) :/
hook.inc
zshell_hook: .db $83 ; used by os for hook safety check (add a,e can be used too) or a jr z,zshell_hook_start ; we just want to handle prgm, not TI-Basic functions zshell_hook_return_z: xor a ret zshell_hook_start: ld hl,(nextparsebyte) ; what's on homescreen ld a,(hl) cp tprog jr nz,zshell_hook_return_z ; if it don't start with "prgm", we don't care rst rmov9toop1 ; we put "prgmANYTHING" into op1 ld hl,op1 ld (hl),progobj ; then replace "prgm" token with the program type (progobj) bcall(_chkfindsym) ; so we can find its datas ex de,hl ; cause of _getbytepaged parameters bjumpc(_errundefined) ; if not found, throw an "undefined error" call get_byte ; else start to read it ld e,a call get_byte ; first two bytes are length of the program jr c,zshell_hook_return_nz ; if empty, don't parse ld d,a dec de dec de ; we don't count the next two bytes (t2bytetok/texttok+tasmcmp/tasm84ccmp) into the program length ld (program_length_count),de call get_byte ; skip t2bytetok/texttok call get_byte cp tasmprgm jr z,zshell_hook_handle_unsquished_asm_prgm cp tasmcmp jr z,zshell_hook_execute_compiled_asm_prgm ;cp tzshellprgm ;ld hl,zshell_txt ;jr z,zshell_hook_execute_zshell_prgm set allowprogtokens,(iy+newdispf) ; allow programming tokens to be parsed in TI-Basic programs ld a,b or a ret z ; the TI-Basic program is unarchived, so let the parser handle it push hl push bc ld hl,zshell_error_handler call app_push_errorh call allocate_temp_prog ; check if there is other temp progs, then put an unique name into op1 ld hl,(program_length_count) push af bcall(_createprotprog) pop af pop bc pop hl bjumpc(_errmemory) push hl push bc inc de inc de ; de = data section (skip the length bytes) xor a ld (parse_var),a ld (parse_var+1),a pop bc pop hl ld a,b ld bc,(program_length_count) bcall(_flashtoram) ; copy the datas from the archived TI-Basic prog to the temp prog bcall(_op4toop1) ; op1 was copied into op4 then destroyed by _createprotprog bcall(_parseinp) call delete_temp_prog call app_pop_errorh zshell_hook_return_nz: or $80 ; reset zero flag, the parser can't continue to parse the variable ret zshell_hook_handle_unsquished_asm_prgm: ld a,b or a jr z,zshell_hook_execute_unsquished_asm_prgm ; todo : unarchive prgm zshell_hook_execute_unsquished_asm_prgm: bcall(_executeprgm) ; can only run unarchived prgm or $80 ret zshell_hook_execute_compiled_asm_prgm: call zshell_hook_program_start_begin zshell_hook_load: push hl ; how many bytes left to copy ld hl,(progaddress) ; copy the program to the gbuf push bc ; hl = program data start ld de,gbuf ; bc = # bytes to copy ldir ; copy bc bytes pop de ; # bytes copied ld (progaddress),hl ; save new program data pointer ; delete bc bytes from the program or a ; hl = start of prog data+768 sbc hl,de push de ; de = # of bytes copied bcall(_delmem) ; hl = where to delete from, de = # bytes pop hl ; hl = # bytes deleted ; insert HL bytes to $9d95 ld de,(progstartlocation) ; progstart ($9d95) push hl ; hl = # bytes deleted bcall(_insertmem) ; insert hl bytes to $9d95 pop bc ; bc = bytes deleted ld hl,(progstartlocation) ; ex de,hl ??? add hl,bc ld (progstartlocation),hl ; copy gbuf to $9d95 ld hl,gbuf ; de = location where memory was inserted ($9d95+XXXX) ldir ; copy # of bytes deleted from gbuf to progstart pop hl ; how many bytes are left to copy ld a,l or h jr nz,zshell_hook_load_loop call progstart ; run the program ; now rewrite the data back into the program ; ...not done yet... zshell_hook_program_start_begin: ld a,b or a call nz,zshell_hook_unarchive ; hl = first byte of program data ; de = program length-2 ld bc,progstart ld (progstartlocation),bc ld (progaddress),hl ex de,hl ; hl = length zshell_hook_load_loop: ld bc,768 ; check if there are <768 bytes left to copy (gbuf length) or a sbc hl,bc ; subtract 768 from the program size ret nc ; if no carry, there are still more than 768 bytes to copy add hl,bc ld b,h ld c,l ld hl,$0000 ret zshell_hook_unarchive: ; push hl ; ld hl,(program_length_count) ; push bc ; bcall(_enoughmem) ; pop bc ; pop hl ; ld a,e_memory ; bjumpc(_jerror) ; ld a,b ; ld de,progstart ; ld bc,(program_length_count) ; inc bc ; inc bc ; we have to count t2bytetok/tprog this time ; bcall(_flashtoram) ; ret zshell_error_handler: res 7,a ; ??? push af call delete_all_temp_progs pop af bjump(_jerror) allocate_temp_prog: ; fail is carry flag is set ld hl,temp_prog_name_str rst rmov9toop1 find_then_allocate_temp_prog: bcall(_chkfindsym) ccf ; inverse the carry flag ret nc ; ret if program not found (we can name it using the ID at op1+2) ld a,(op1+2) dec a scf ; set carry flag in case we ret (meaning we can't allocate the temp prog, but there's a few chance for that) ret z ; ret if a = 0 ld (op1+2),a jr find_then_allocate_temp_prog delete_temp_prog: ld hl,temp_prog_name_str rst rmov9toop1 ld a,1 ld (op1+2),a ; we start by checking the temp prog with the ID = 01 find_then_delete_temp_prog: bcall(_chkfindsym) jr nc,delete_temp_prog_ok ; if the temp prog is found, delete it ld a,(op1+2) ; else we increase the prog id inc a scf ; if we're over $ff, there's no more temp prog ret z ld (op1+2),a jr find_then_delete_temp_prog delete_temp_prog_ok: bcall(_delvararc) xor a ret delete_all_temp_progs: call delete_temp_prog ret c jr delete_all_temp_progs temp_prog_name_str: .db protprogobj,$01,$ff,0

zSHELL.zip

J'ai aussi du mal à comprendre le handler des erreurs, et notamment pourquoi est-ce qu'il faut faire un "res 7,a" ?
chickendude (./26) :
On pourrait peut-être écire un autre hook pour le token prgm, quand on exécute ce token notre hook cherchera le programme et le desarchiver s'il est dans l'archive avant de le faire courir.

Il me semble que noshell/zstart font ça (d'où l'utilisation de programmes temporaires avec un ID unique dans le nom), il faudra que je vérifie. On aura peut être même pas besoin de créer un nouvel hook.