; This is the ucode used to "unlock" memcards
; RE purely out of interest, and hunch that it does trickies

IROM_BASE:	equ	0x8000

; Exception vectors
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	halt	; Exception 0-6 nop slide to here
	rti		; Exception 7
	halt

; Entry point
; Standard init stuff
	sbset	#0x06
	sbclr	#0x03
	sbclr	#0x04
	sbset	#0x05
	lri		$CR, #0x00ff
	lri		$WR0, #0xffff
	lri		$WR1, #0xffff
	lri		$WR2, #0xffff
	lri		$WR3, #0xffff
	set40

; 0xdcd10000 is the init mail
	call	wait_for_dsp_mbox
	si		@DMBH, #0xdcd1
	si		@DMBL, #0x0000
	si		@DIRQ, #0x0001
; Wait for cpu to say "go!" - i think
wait_for_start_cmd:
	call	wait_for_cpu_mbox
	lrs		$AC1.L, @CMBL
	cmpi	$AC1.M, #0xff00
	jnz		wait_for_start_cmd

dma_dram_and_prepare_for_crazy_irom_func:
	call	wait_for_cpu_mbox
	mrr		$AC0.M, $AC1.M
	lrs		$AC0.L, @CMBL	; main ram addr.l
	andi	$AC0.M, #0x0fff ; main ram addr.h & 0x0fff
	lri		$AX0.L, #0x0400	; dsp addr
	lri		$AX0.H, #0x0010 ; length (bytes)
	lri		$AX1.L, #0x0000	; dsp dram to cpu
	set16
	call	do_dma
	call	IROM_BASE+0x0644; holy mother of jesus that func is gonna be hard

; 0xdcd10003 means finished unlocking?
	call	wait_for_dsp_mbox
	si		@DMBH, #0xdcd1
	si		@DMBL, #0x0003
	si		@DIRQ, #0x0001
	set40
	call	wait_for_cpu_mbox
	cmpi	$AC1.M, #0xcdd1
	jnz		dma_dram_and_prepare_for_crazy_irom_func
	lrs		$AC1.M, @CMBL
	cmpi	$AC1.M, #0x0001
	jz		_005afunc
	cmpi	$AC1.M, #0x0002
	jz		IROM_BASE		; End of this ucode, wait for a new one
	jmp		dma_dram_and_prepare_for_crazy_irom_func
	halt	; Prolly never reached

; 10 mails from cpu then irom func - looks interesting
_005afunc:
	set16
	call	wait_for_cpu_mbox
	lrs		$AC1.L, @CMBL
	call	wait_for_cpu_mbox
	lrs		$AC1.L, @CMBL
	call	wait_for_cpu_mbox
	lrs		$AC1.L, @CMBL
	call	wait_for_cpu_mbox
	lr		$IX1, @CMBL
	andi	$AC1.M, #0x0fff
	mrr		$IX0, $AC1.M
	call	wait_for_cpu_mbox
	lr		$IX3, @CMBL
	call	wait_for_cpu_mbox
	lr		$IX2, @CMBL
	call	wait_for_cpu_mbox
	lr		$AR0, @CMBL
	call	wait_for_cpu_mbox
	lrs		$AX0.L, @CMBL
	andi	$AC1.M, #0x0fff
	mrr		$AX0.H, $AC1.M
	call	wait_for_cpu_mbox
	lrs		$AX1.L, @CMBL
	call	wait_for_cpu_mbox
	lrs		$AX1.H, @CMBL
	sbclr	#0x05
	sbclr	#0x06
	jmp		IROM_BASE+0x00b5; IROM - can dma stuff
	halt

wait_for_dsp_mbox:
	lrs		$AC1.M, @DMBH
	andcf	$AC1.M, #0x8000
	jlz		wait_for_dsp_mbox
	ret

wait_for_cpu_mbox:
	lrs		$AC1.M, @CMBH
	andcf	$AC1.M, #0x8000
	jlnz	wait_for_cpu_mbox
	ret

do_dma:
	srs		@DSMAH, $AC0.M
	srs		@DSMAL, $AC0.L
	sr		@DSPA, $AX0.L
	sr		@DSCR, $AX1.L
	sr		@DSBL, $AX0.H
wait_dma:
	lrs		$AC0.M, @DSCR
	andcf	$AC0.M, #0x0004
	jlz		wait_dma
	ret

; Trailing nops...pad to 32bytes
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop

; uCode is 0xb0 words