64Fermer66
FarewellLe 07/08/2009 à 18:52
J'ai... euh... un peu optimisé le handler de fline ... fear

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. ^^