;;  linux booter, assembler stuff to start it off
;;  (c) RZ

/* what it does is this ...:		
    _super(); 
    disable_interrupts();
    disable_cache();
    disable_mmu();
    memcpy ((void *) 0x18000, &copyall, &copyallend - &copyall);
    change_stack ((void *) 0x20000);
    jump_to_mover((char *) start_mem, memptr,
		  (char *) bi.ramdisk.addr + rd_size, memptr + memreq,
		  kernel_size + bi_size, rd_size,
		  (void *) 0x18000);
*/
	.sect 	.text
	.extern _linux_init

_linux_init:
	trap	#0		; super
	or.w	#$700,sr	; ints off

	dc.w	$f478		; cpusha %dc
	dc.w	$f4b8		; cpusha %ic

	moveq	#0,d0
	moveq	#0,d1
	dc.w	$4e7b,$1002	; movec d1,cacr	 - cache off
	tst.l	_is060
	beq	no060
	move.l	$00400000,d1
	dc.w	$4e7b,$1002
	dc.l	$4e7b0808
no060:
	dc.l	$4e7b0003	; movec	d0,tc    - MMU off
	dc.l	$4e7b0004	; movec d0,itt0
	dc.l	$4e7b0005	; movec d0,itt1
	dc.l	$4e7b0006	; movec d0,dtt0
	dc.l	$4e7b0007	; movec d0,dtt1  - ttc off

;;; memcpy ((void *) 0x18000, &copyall, &copyallend - &copyall)
	lea	_copyall,a0
	lea	0x18000,a1
	lea	_copyallend,a2
	addq.l	#4,a2		
cll:	move.l	(a0)+,(a1)+
	cmp.l	a0,a2
	bcc	cll	

;;;  change stack ???
	lea	0x20000,a7

;;; jump_to_mover((char *) start_mem, memptr,
;;; 		  (char *) bi.ramdisk.addr + rd_size, memptr + memreq,
;;; 		  kernel_size + bi_size, rd_size,
;;; 		  (void *) 0x18000);
	move.l	_arg1,a0	; _kernel_start
	move.l	_arg2,a1	; _start_mem
	move.l	_arg3,a2 
	move.l	_arg4,a3
	move.l	_arg5,d0
	move.l	_arg6,d1

	lea	$18000,a6
	jmp	(a6)

;;; no return

;;; mover code:
_copyall:
	move.l	a0,a4		;  save kernel_start
cl1:	move.l	(a1)+,(a0)+	;  copy kernel
	subq.l	#4,d0
	bcc	cl1

	tst.l	d1
	beq	cl3

cl2:	move.l	-(a3),-(a2)	;  copy ramdisk starting at the end
	subq.l	#4,d1
	bcc	cl2

cl3:
	move.b	#1,$ff000030    ; turn on LED
	jmp	(a4)		; wow, that's it !!

	ds.l	4		; some extra space..

_copyallend:	
	dc.l 	0
	ds.l	4		; .. to beware of optimisations...



	end
