hmmm ... une table de saut n'aurait pas été plus courte ?
moveq.l #0,d1
move.b RAM_TABLE_JUMP(pc,d0.w),d1
.....
jmp jump(pc,d1.w)
jump:
label_offset_fonction: jmp a0
label_offset_data: move.l a0,d0
label_offset_ptr: rts
Qu'en pensez-vous ?
Folco (./33) :
Le concept répond à mes besoins, oui, j'attends pour modifier eexec que tu valides l'interface.Mais à priori, ça devrait cartonner avec ça, ya pas de raison
(et ya pas mal à gagner en place, plus besoin de loader, utiliser kernel::exit deviendra systématique, ça va être chouette ^^)
--- Vectors.asm.old 2009-07-16 20:41:31.000000000 +0200 +++ Vectors.asm 2009-07-22 20:51:58.000000000 +0200 @@ -147,38 +147,57 @@ ; ROM_CALL avec un word. ; Example: dc.w $FFF2, HeapAlloc*4 LINE_1111: - move.w (sp)+,d1 ; Get Old SR - move.l (sp)+,a0 ; Get Address of the 'crash' - move.w (a0)+,d0 ; We get the instruction and a0 ->next instruction - subi.w #$F800,d0 ; Is it > $F800 ? + move.w (sp)+,d2 ; Get Old SR + move.l (sp)+,a1 ; Get Address of the 'crash' + move.w d2,SR ; Restore SR + move.w (a1)+,d2 ; We get the instruction and a0 ->next instruction + cmpi.w #$F800,d2 bls.s \no ; No, so it is a crash (First_Window isn't a ROM_CALL) - move.l a0,a1 ; Jsr/Jmp with a 32 bits offset - cmp.w #$FFF0-$F800,d0 + subi.w #$F800,d2 + move.l a1,a0 ; Jsr/Jmp with a 32 bits offset + cmp.w #$FFF0-$F800,d2 bne.s \NoRelJsr - adda.l (a0)+,a1 ; Get the Sub Routine + adda.l (a1)+,a0 ; Get the Sub Routine bra.s \Jump -\NoRelJsr cmp.w #$FFF1-$F800,d0 +\NoRelJsr cmp.w #$FFF1-$F800,d2 bne.s \NoRelJmp - adda.l (a0)+,a1 ; Get the Sub Routine - move.w d1,SR ; Restore SR - jmp (a1) ; Jmp with a 32 bits offset -\NoRelJmp cmp.w #$FFF2-$F800,d0 + adda.l (a1)+,a0 ; Get the Sub Routine + jmp (a0) ; Jmp with a 32 bits offset +\NoRelJmp cmp.w #$FFF2-$F800,d2 bne.s \NoBigRomCall - move.w (a0)+,d0 ; Read Offset - lsr.w #2,d0 -\NoBigRomCall move.l ($C8).w,a1 ; The address of the rom_call table - cmp.w -(a1),d0 ; Compare rom_call and number of entries - bcc.s \no ; Out of range ? => Crash - move.w d0,(VAR_SYSTEM1).w ; For debug purpose - lsl.w #2,d0 ; * 4 - move.l 2(a1,d0.w),a1 ; + ($C8) MAX: 8000 rom_calls -\Jump move.w d1,SR ; Restore SR - pea (a0) ; Push return address - jmp (a1) ; Jump to Rom_call function -\no: lea Line1111_str(Pc),a0 + move.w (a1)+,d2 ; Read Offset + lsr.w #2,d2 +\NoBigRomCall move.l ($C8).w,a0 ; The address of the rom_call table + cmp.w -(a0),d2 ; Compare rom_call and number of entries + bcc.s \error ; Out of range ? => Crash + move.w d2,(VAR_SYSTEM1).w ; For debug purpose + lsl.w #2,d2 ; * 4 + move.l 2(a0,d2.w),a0 ; + ($C8) MAX: 8000 rom_calls +\Jump pea (a1) ; Push return address + jmp (a0) ; Jump to Rom_call function +\no: subi.w #$F000,d2 ; Clear data of exception + cmpi.w #MAX_RAMCALL,d2 ; Valid ramcall ? + bcc.s \error ; No, throw an error + pea (a1) ; Push return adress + lsl.w #2,d2 ; Table of longwords + lea.l RAM_TABLE(pc),a1 ; Read the ramcall table ptr + adda.w d2,a1 ; Add offset : a0 now points to the ramcall + movea.l (a1),a1 ; Read it + lsr.w #2,d2 ; Table of bytes + move.b RAM_TABLE_TYPE(pc,d2.w),d2 ; Red type of ramcall (table of bytes) + bmi.s \ReturnPtr ; -1 : return a ptr in a0 + beq.s \ReturnData ; 0 : return data in d0 + jmp (a1) ; 1 : else jump to the function +\ReturnData: move.l a1,d0 ; Data must be in d0 +\ReturnPtr: movea.l a1,a0 ; Else it's a ptr, put it in a0 + rts +\error: lea Line1111_str(Pc),a0 bra FATAL_ERROR - +RAM_TABLE_TYPE ; -1 : ptr. 0 : data. +1 : routine + dc.b -1,0,0,-1,0,0,0,0,0,0,0,0,0,-1,-1,0,-1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,0,0,0,0,0,1,1,1,1,-1,-1,-1 + + Trap_7: Trap_8: Trap_10: ; Enter self test
PpHd, tu veux aussi gérer les ROM_CALLs qui sont des variables (genre FiftyMsecTick)?
la seule interface raisonnable est de retourner le résultat dans %a0.l quel que soit le RAM_CALL.
Lionel Debroux (./41) :la seule interface raisonnable est de retourner le résultat dans %a0.l quel que soit le RAM_CALL.Pas bon pour les RAM_CALLs qui prennent un argument dans a0...
Lionel Debroux (./41) :
rester en mode superviseur le temps de l'exécution du handler, modifier sur la pile superviseur l'adresse de retour (sans oublier, si c'est nécessaire, par exemple pour les ROM_CALLs en F-Line, de pousser l'adresse de retour du ROM_CALL sur la pile utilisateur), et utiliser RTE;
Lionel Debroux (./41) :
On peut aussi pousser sur la pile d0-d7/a0-a6 tout au début du handler, les modifier comme nécessaire sur la pile superviseur pour le retour, et les restaurer juste avant le RTE.
-> le reste : encore une fois, qu'est-ce qui te dis qu'on est en utilisateur à la base ?
(même si je ne suis pas sûr qu'il soit fréquent d'utiliser des ROM_CALLs en F-Line quand on est en mode superviseur)
; If $FFF0, ; ~ jsr abs.l (Return address +6 / jsr to a1 ->Crash code+2 a1+(a1) ; Ex: dc.w $FFF0 dc.l JumpAdr-* ; If $FFF2, ; ROM_CALL avec un word. ; Example: dc.w $FFF2, HeapAlloc*4 LINE_1111: movem.l d0-d2/a0-a3,-(sp) ; Musn't trash any register for ramcalls. a3 won't be trashed, but it reserves space move.w 4*7(sp),d1 ; Get Old SR movea.l 4*7+2(sp),a0 ; Get Address of the 'crash' move.w (a0)+,d0 ; We get the instruction and a0 ->next instruction cmpi.w #$F800,d0 ; Is it > $F800 ? bls.s \ramcall ; No, so it is perhaps a ramcall (FirstWindow is not a romcall) lea.l 4*7+6(sp),sp ; Pop 7 registers + SR + Address of the 'crash' subi.w #$F800,d0 ; Clean data movea.l a0,a1 ; Jsr/Jmp with a 32 bits offset cmpi.w #$FFF0-$F800,d0 bne.s \NoRelJsr adda.l (a0)+,a1 ; Get the Sub Routine bra.s \Jump \NoRelJsr cmpi.w #$FFF1-$F800,d0 bne.s \NoRelJmp adda.l (a0)+,a1 ; Get the Sub Routine move.w d1,SR ; Restore SR jmp (a1) ; Jmp with a 32 bits offset \NoRelJmp cmpi.w #$FFF2-$F800,d0 bne.s \NoBigRomCall move.w (a0)+,d0 ; Read Offset lsr.w #2,d0 \NoBigRomCall movea.l ($C8).w,a1 ; The address of the rom_call table cmp.w -(a1),d0 ; Compare rom_call and number of entries bcc.s \crash ; Out of range ? => Crash move.w d0,(VAR_SYSTEM1).w ; For debug purpose lsl.w #2,d0 ; * 4 movea.l 2(a1,d0.w),a1 ; + ($C8) MAX: 8000 rom_calls \Jump move.w d1,SR ; Restore SR pea (a0) ; Push return address jmp (a1) ; Jump to Rom_call function \ramcall: subi.w #$F000,d0 ; Clean data cmpi.w #MAX_RAMCALL,d0 ; Valid ramcall ? bcc.s \crash ; No, it's a crash move.b RAM_TABLE_TYPE(pc,d0.w),d2 ; Read type of ramcall (table of bytes) lea RAM_TABLE(pc),a1 ; Ptr to the ramcall table lsl.w #2,d0 ; Table of longwords movea.l 0(a1,d0.w),a1 ; Read ramcall tst.b d2 ; What type of ramcall ? bmi.s \ReturnPtr ; -1 : return a ptr in a0 beq.s \ReturnData ; 0 : return data in d0 btst.b #5,28(sp) ; Called in supervisor mode ? beq.s \UserMode ; No move.w 7*4(sp),6*4(sp) ; Rewrite SR (need another return adress on the stack) move.l a1,6*4+2(sp) ; Set the ramcall ptr as the return adress of the handler move.l a0,7*4+2(sp) ; Push the return adress of the ramcall movem.l (sp)+,d0-d2/a0-a2 ; Restore registers, but not a3 which hasn't ben destroyed rte ; And quit the handler, calling the ramcall \UserMode: move.l USP,a2 ; Read user stack pointer move.l a0,-(a2) ; And push the return adress of the ramcall move.l a2,USP ; Save the new stack pointer move.l a1,4*7+2(sp) ; Set the ramcall ptr as the return adress of the handler movem.l (sp)+,d0-d2/a0-a3 ; Restore all registers rte ; Call ramcall \ReturnPtr: move.l a1,12(sp) ; Modify saved a0 bra.s \EndDataPtr ; Useless ? \ReturnData: move.l a1,(sp) ; Modify saved d0 \EndDataPtr: movem.l (sp)+,d0-d2/a0-a3 ; Restore destroyed registers addq.l #2,2(sp) ; Return adress points now after the 'crash' rte ; And come back \crash: lea Line1111_str(Pc),a0 bra FATAL_ERROR RAM_TABLE_TYPE: ; -1 : ptr. 0 : data. +1 : routine dc.b -1,0,0,-1,0,0,0,0,0,0,0,0,0,-1,-1,0,-1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,0,0,0,0,0,1,1,1,1,-1,-1,-1 even
PpHd (./50) :
C'est l'idée.
PpHd (./50) :
A noter que s'il faut retourner une donnée dans d0 ou une addresse dans a0, tu peux dans les 2 cas retourner les 2 dans les 2 registres. Ca simplifie le code.
+ cmpi.w #$F800,d0 ; Is it > $F800 ? + bls.s \ramcall ; No, so it is perhaps a ramcall (FirstWindow is not a romcall) + lea.l 4*7+6(sp),sp ; Pop 7 registers + SR + Address of the 'crash' + subi.w #$F800,d0 ; Clean data ... +\ramcall: + subi.w #$F000,d0 ; Clean data
+ subi.w #$F800,d0 ; Is it > $F800 ? + bls.s \ramcall ; No, so it is perhaps a ramcall (FirstWindow is not a romcall) + lea.l 4*7+6(sp),sp ; Pop 7 registers + SR + Address of the 'crash' ... +\ramcall: + addi.w #$800,d0 ; Clean data
Just add '!' before the filename you don't want to compresse (The first file MUST be compressed !)
.include "kernel.h" _main: .xdef _main .xdef _ti89 .xdef _ti89ti .xdef _ti92plus .xdef _v200 .xdef _flag_2 |console apps : no redraw screen jmp eexeclib__0000
.xdef _nostub __main: .xdef __main .xdef _ti89 .xdef _ti89ti .xdef _ti92plus .xdef _v200 __main: clr.l -(%sp) |function + version bsr.s Push .asciz "exclb" Push: .word 0xF000+ <LibsExec>
Folco (./56) :
Ah mais nan c'est pas possible ça !T'es vraiment très sûr que c'est vraiment très très obligatoire ? :'(
Folco (./56) :
Faster, smaller, harder, stronger![]()
Folco (./58) :
Eh merde.Mais au moins, les ramcalls en fline seront dans la prochaine RC ? #retient_son_souffle"
Folco (./53) :
Tout marche du premier coup !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!