J'ai... euh... un peu optimisé le handler de fline ...

Euh... bon voilà :
; 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
;; Copyright 2009 Martial Demolins
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
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'
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
lsl.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
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:
addi.w #$F800-$F000,d0 ; Clean data
cmpi.w #MAX_RAMCALL,d0 ; Valid ramcall ?
- bcc.s \crash ; No, it's a crash ( >= )
+ bcc.s \CheckPedroMCall ; No, it's a crash ( >= )
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
cmp.l #kernel::BeginSharedLinker,a1 ; Compare the address. Is-it inside the PreOs kernel routine?
bcs.s \NotAFunctionCall
cmp.l #kernel::EndSharedLinker,a1 ; Compare the address. Is-it inside the PreOs kernel routine?
bhi.s \NotAFunctionCall
- btst.l #5,d1 ; Called in supervisor mode ?
+\FunctionCall: btst.l #5,d1 ; Called in supervisor mode ?
beq.s \UserMode ; No
move.w d1,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
\NotAFunctionCall:
move.l a1,3*4(sp) ; Modify saved a0
move.l a1,(sp) ; Modify saved d0
movem.l (sp)+,d0-d2/a0-a3 ; Restore destroyed registers
addq.l #2,2(sp) ; Fix adress points after the 'crash'
rte ; And come back
+\CheckPedroMCall:
+ addi.w #$F100-F000,d0 ; PedroM lib calls : $F100 + #func/var
+ cmpi.w #MAX_PEDROM_CALL,d0 ; Out of range ?
+ bcc.s \crash
+ lea.l PedroMLibExportTable+2(Pc),a1 ; Ptr to the PedroM calls table
+ lsr.w #2,d0 ; Table of longwords
+ movea.l 0(a1,d0.w),a1 ; Read PedroM call
+ cmp.l #pedrom::BeginVariablesTable,a1 ; Inside variables table ?
+ bcc.s \FunctionCall
+ cmp.l #pedrom::EndVariablesTable,a1
+ bhi.s \FuntionCall
+ bra.s \NotAFunctionCall
\crash: lea Line1111_str(Pc),a0
bra FATAL_ERROR
(Au fait, le label s'appelle
PedomLibExportTable dans Library.asm ^^)
En fait, pour utiliser les appels de PedroM en flash, je dois faire ça :
PrintAndQuit:
pea.l 4<<16+0 | Push function + version (pedrom:: printf)
bsr.s PushStrPedroM | Push lib name
.asciz "pedrom" | Lib name
.even
PushStrPedroM:
RAMC RAM_kernel__LibsExec | kernel::LibsExec(pedrom:: printf)
lea.l 12(%sp),%sp | *string + function+version + pedrom str
rts | And quit
Avec le patch, plus besoin. C'est peut-être bien d'avoir les appels système dans un vecteurs, non ?
=> Pas compilé ni testé, j'ai ce message quand j'essaye :
c:\Documents and Settings\user\>make
'make' n'est pas reconnu en tant que commande interne ou externe, un programme éxécutable ou un fichier de commande
Et là j'ai rien d'autre sous la main. ^^