incdir "tests"
include "dsp_base.inc"

; We'll let dsp_base.inc catch exceptions
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;halt        
;rti         
;halt        

sbset       #0x06
sbclr       #0x03
sbclr       #0x04
sbset       #0x05
lri         $CR, #0x00ff
lri         $WR0, #0xffff
lri         $WR1, #0xffff
lri         $WR2, #0xffff
lri         $WR3, #0xffff
set40       
m0          
clr15       

;step 1: context setup
call		send_back_40

call        0x807e			; loop until DSP->CPU mailbox is empty
si          @DMBH, #0xdcd1
si          @DMBL, #0x0000	; sendmail 0xdcd10000
si          @DIRQ, #0x0001

; wait for CPU mail == 0xabbaxxxx
wait_cpu_init:
call        0x8078
lrs         $AC0.L, @CMBL
cmpi        $AC0.M, #0xabba
jnz         wait_cpu_init

; Next mail has the mram addr of the data to fetch
set16       
call        0x8078
lrs         $AX0.L, @CMBL
andi        $AC0.M, #0x0fff
mrr         $AX0.H, $AC0.M
lri         $AX1.H, #0x0000	; DSP-DRAM addr
lri         $AX1.L, #0x0020	; length (32 bytes = 16 words, word 9 and 10 are addr where result should DMA'd to in main mem)
lri         $IX3, #0x0000	; there will be no ucode/iram upload
lri         $AR0, #do_main	; return addr after DRAM upload
jmp         0x80bc			; DRAM upload !!
; $AX0.H-$AX0.L - CPU(PPC) addr = mail & 0x0fffffff
; upload data from mainmem to DSP DRAM and jump to 0x41 after that

; ucode addr 0x0041
do_main:
;step 2: got data from CPU, before going into BigCrazyFunction
call		send_back

call        BigCrazyFunction		; <<------------- main crap is here!!!!!!!!!
call        0x807e					; loop until DSP->CPU mailbox is empty

si          @DMBH, #0xdcd1
si          @DMBL, #0x0003			; sendmail 0xdcd10003 (aka... calc is over, result is in main mem now)
si          @DIRQ, #0x0001
set40       

; wait for CPU to tell us what to do after calc'ing
wait_cpu_end:
call        0x8078
cmpi        $AC0.M, #0xcdd1
jnz         wait_cpu_end

lrs         $AC0.M, @CMBL
cmpi        $AC0.M, #0x0001
jz          PrepareBootUcode		; if CPU->DSP mail was 0xcdd10001 -> 005e_PrepareBootUcode()

cmpi        $AC0.M, #0x0002
jz          0x8000					; if CPU->DSP mail was 0xcdd10002 -> DSP reset ( jmp to irom(0x8000))

; THIS IS CUSTOM CODE
cmpi        $AC0.M, #0xbabe
jz          end_of_test				; wait for DSP to be reset by CPU

jmp         wait_cpu_end			; wait for next mail from CPU
halt        


PrepareBootUcode:
set16       
call        0x8078
lrs         $AC0.L, @CMBL
call        0x8078
lrs         $AC0.L, @CMBL
call        0x8078
lrs         $AC0.L, @CMBL
call        0x8078
lr          $IX1, @CMBL
andi        $AC0.M, #0x0fff
mrr         $IX0, $AC0.M
call        0x8078
lr          $IX3, @CMBL
call        0x8078
lr          $IX2, @CMBL
call        0x8078
lr          $AR0, @CMBL
call        0x8078
lrs         $AX0.L, @CMBL
andi        $AC0.M, #0x0fff
mrr         $AX0.H, $AC0.M
call        0x8078
lrs         $AX1.L, @CMBL
call        0x8078
lrs         $AX1.H, @CMBL
sbclr       #0x05
sbclr       #0x06
jmp         0x80b5		; BootUcode()
halt     


; does some crazy stuff with data at DRAM @0x3/0x5/0x6/0x7 with help of some values from drom :)
; result is @0x22,@0x23 and written back to main memory to dmem-0x08:dmem-0x09
BigCrazyFunction:
; {
clr         $ACC0
lri         $AR1, #0x0010
loopi       #0x20
	srri        @$AR1, $AC0.M
call		send_back ;3
lr          $AC1.M, @0x1456
call		send_back
andi        $AC1.M, #0xffd0
call		send_back
clrp'mv     : $AX1.L, $AC1.M		; assembler doesn't like .m here
call		send_back
lri         $AR0, #0x0000
call		send_back
lri         $IX2, #0x0000
call		send_back
lri         $AR2, #0x001f
call		send_back
lr          $AC0.M, @0x15f6
call		send_back
lsl         $ACC0, #8
call		send_back
lr          $AC1.M, @0x1766
call		send_back
andi        $AC1.M, #0x00ff
call		send_back
mrr         $AX0.H, $AC1.M
call		send_back
call        0x88e5
call		send_back
mrr         $AX0.L, $AC0.L
call		send_back
clr'mv      $ACC0 : $AX1.H, $AC0.M	; assembler doesn't like .m here
call		send_back
lrri        $AC0.M, @$AR0
call		send_back
lsr         $ACC0, #-8
call		send_back
mrr         $AC1.M, $AC0.L
call		send_back
mrr         $AX0.H, $AC0.M
call		send_back
call        0x8809
call		send_back
call        0x8723
call		send_back
dar         $AR2
call		send_back
clr'dr      $ACC0 : $AR2
call		send_back
lr          $AC0.M, @0x166c
call		send_back
lsl         $ACC0, #4
call		send_back
andi        $AC0.M, #0xff00
call		send_back
lr          $AC1.M, @0x1231
call		send_back
lsr         $ACC1, #-8
call		send_back
andi        $AC1.M, #0x00ff
call		send_back
mrr         $AX0.H, $AC1.M
call		send_back
call        0x88e5
call		send_back
mrr         $AX0.L, $AC0.L
call		send_back
clr'mv      $ACC0 : $AX1.H, $AC0.M	; assembler doesn't like .m here
call		send_back
lrri        $AC0.M, @$AR0
call		send_back
lsr         $ACC0, #-8
call		send_back
mrr         $AC1.M, $AC0.L
call		send_back
mrr         $AX0.H, $AC0.M
call		send_back
call        0x8809
call		send_back
call        0x8723
call		send_back
clr         $ACC0
call		send_back
clr         $ACC1
call		send_back
lr          $AC1.H, @0x0005
call		send_back
asr16       $ACC1
call		send_back
cmp         
call		send_back ;46
jz          Unk_00e5
call		send_back ;47
jl          Unk_00f3
call		send_back ;48

; if ( > ) {
; length 12
lri         $AR2, #0x0010
call		send_back
lri         $IX2, #0x0001
call		send_back
lr          $AC0.H, @0x171b
call		send_back
asr16       $ACC0
call		send_back
neg         $ACC1
call		send_back
add         $ACC1, $ACC0
call		send_back
lsl         $ACC1, #1
call		send_back
mrr         $AX0.H, $AC1.M
call		send_back
lr          $AC1.M, @0x0003
call		send_back
lsl         $ACC1, #4
call		send_back
call        0x8809
call		send_back
jmp         Unk_0102
call		send_back ;60

; } else if ( == 0) {
; length 8
Unk_00e5:
lri         $AR2, #0x0011
call		send_back
lr          $AC1.M, @0x0003
call		send_back
lsl         $ACC1, #1
call		send_back
mrr         $AX0.H, $AC1.M
call		send_back
lr          $AC0.M, @0x1043
call		send_back
andi        $AC0.M, #0xfff0
call		send_back
call        0x88e5
call		send_back ;53
jmp         Unk_0102

; } else if ( < ) {
; length 10
Unk_00f3:
lri         $AR2, #0x0010
call		send_back
lri         $IX2, #0x0001
call		send_back
lr          $AC0.H, @0x1285
call		send_back
asr16       $ACC0
call		send_back
add         $ACC1, $ACC0
call		send_back
lsl         $ACC1, #1
call		send_back
lr          $AC0.M, @0x0003
call		send_back
lsl         $ACC0, #4
call		send_back
mrr         $AX0.H, $AC0.M
call		send_back
call        0x8809
call		send_back ;57
; }

Unk_0102:
lri         $AR3, #0x0013
call		send_back ; either step 60, 53, 57
srri        @$AR3, $AC0.M
call		send_back
clr's       $ACC1 : @$AR3, $AC0.L
call		send_back
lri         $AR3, #0x0013
call		send_back
lr          $AC1.M, @0x0007
call		send_back
lr          $AC0.M, @0x11b8
call		send_back
andi        $AC0.M, #0xfff0 ;66
call		send_back
mrr         $AX0.H, $AC0.M
call		send_back

;call        0x81f4
mulxac'mv   $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M
call		send_back
asr16'ir    $ACC1 : $AR1
call		send_back ;66
srri        @$AR3, $AC1.M
call		send_back
clr's       $ACC0 : @$AR3, $AC1.L

call		send_back
lsl16       $ACC1
call		send_back

;call        0x8458 ;66
mulxac'mv   $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M
call		send_back
asr16       $ACC1
call		send_back
srri        @$AR3, $AC1.M
call		send_back
clr's       $ACC0 : @$AR3, $AC1.L
call		send_back


call		send_back
set40       
call		send_back_40
lri         $AR2, #0x0015
call		send_back_40
lr          $AC0.M, @0x0006
call		send_back_40
lr          $AX0.H, @0x165b
call		send_back_40
call        0x88e5
call		send_back_40
asr         $ACC0, #-3
call		send_back_40
lsl         $ACC0, #3
call		send_back_40
srri        @$AR2, $AC0.M
call		send_back_40
srri        @$AR2, $AC0.L
call		send_back_40
lri         $AR2, #0x0016
call		send_back_40
lr          $AC0.M, @0x1723
call		send_back_40
asr         $ACC0, #-12
call		send_back_40
lr          $AX0.H, @0x166b
call		send_back_40
call        0x88e5
call		send_back_40
tst         $ACC0
call		send_back_40
jge         Unk_012e
call		send_back_40

clr         $ACC0
call		send_back_40

Unk_012e:
asr         $ACC0, #-3
call		send_back_40
set16       
;step 4
call		send_back
lr          $AC1.M, @0x1491
call		send_back
andi        $AC1.M, #0xd0f0
call		send_back
mrr         $IX1, $AC1.M
call		send_back
lr          $AC1.M, @0x1468
call		send_back
lr          $AC1.H, @0x11fc
call		send_back
lsr         $ACC1, #-4
call		send_back
mrr         $IX2, $AC1.M
call		send_back
lr          $AC1.H, @0x11b8
call		send_back
asr16       $ACC1
call		send_back
lsl         $ACC0, #24
call		send_back
lsr         $ACC0, #-8
call		send_back
mrr         $AX0.H, $AC0.M
call		send_back
mrr         $AC1.M, $AC0.M
call		send_back
mrr         $AX1.H, $IX1
call		send_back
andr        $AC0.M, $AX1.H
call		send_back
lsl         $ACC0, #2
call		send_back
mrr         $AX1.H, $IX2
call		send_back
andr        $AC1.M, $AX1.H
call		send_back
lsl         $ACC1, #1
call		send_back
add         $ACC0, $ACC1
call		send_back
lsl         $ACC1, #24
call		send_back
asr16       $ACC1
call		send_back
andr        $AC1.M, $AX0.H
call		send_back
add         $ACC0, $ACC1
call		send_back
lr          $AC1.M, @0x0012
call		send_back
orc         $AC1.M, $AC0.M
call		send_back
sr          @0x0012, $AC1.M
call		send_back
lsr         $ACC0, #-16
call		send_back
lr          $AC1.M, @0x0011
call		send_back
orc         $AC1.M, $AC0.M
call		send_back
sr          @0x0011, $AC1.M
call		send_back
mrr         $AC1.L, $IX1
call		send_back
lsl         $ACC1, #1
call		send_back
mrr         $AC1.M, $IX2
call		send_back
lsl16       $ACC1
call		send_back
asr         $ACC1, #-8
call		send_back
lsr16       $ACC1
call		send_back
mrr         $AX0.H, $AC1.M
call		send_back
mrr         $AX1.H, $AC1.L
call		send_back
clr         $ACC0
call		send_back
lr          $AC0.M, @0x0011
call		send_back
andr        $AC0.M, $AX0.H
call		send_back
clr         $ACC1
call		send_back
lr          $AC1.M, @0x0012
call		send_back
andr        $AC1.M, $AX0.H
call		send_back
add         $ACC0, $ACC1
call		send_back
lr          $AC1.M, @0x0012
call		send_back
lsr         $ACC1, #-8
call		send_back
add         $ACC0, $ACC1
call		send_back

call		send_back
clr         $ACC1
call		send_back
mrr         $AC1.M, $AC0.M
call		send_back
lsl         $ACC1, #8
call		send_back
orr         $AC1.M, $AX1.H
call		send_back
lr          $AC0.M, @0x0011
call		send_back
orc         $AC0.M, $AC1.M
call		send_back
lr          $AC1.M, @0x0012
call		send_back
orr         $AC1.M, $AX1.H
call		send_back
mrr         $IX1, $AC1.M
call		send_back
lr          $AX0.H, @0x15f1
call		send_back
andr        $AC1.M, $AX0.H
call		send_back
jz          else_0192
call		send_back
; if () {

	lr          $AC1.M, @0x10e2
call		send_back
	lsl         $ACC1, #8
call		send_back
	mrr         $AX0.H, $AC1.M
call		send_back
	lr          $AC1.M, @0x103b
call		send_back
	decm        $AC1.M
call		send_back
	orr         $AC1.M, $AX0.H
call		send_back
	xorc        $AC0.M, $AC1.M
call		send_back
	sr          @0x0022, $AC0.M
call		send_back
	lr          $AC0.L, @0x1229
call		send_back
	lr          $AC1.L, @0x11f8
call		send_back
	sub         $ACC0, $ACC1
call		send_back
	lsl16       $ACC0
call		send_back
	mrr         $AC1.M, $IX1
call		send_back
	xorc        $AC0.M, $AC1.M
call		send_back
	jmp         Unk_01a5
call		send_back
	
; } else {
else_0192:
	lr          $AC1.M, @0x10ca
call		send_back
	lsl         $ACC1, #8
call		send_back
	mrr         $AX0.H, $AC1.M
call		send_back
	lr          $AC1.M, @0x1043
call		send_back
	incm        $AC1.M
call		send_back
	orr         $AC1.M, $AX0.H
call		send_back
	xorc        $AC0.M, $AC1.M
call		send_back
	sr          @0x0022, $AC0.M
call		send_back
	lr          $AC0.L, @0x1259
call		send_back
	lr          $AC1.L, @0x16fe
call		send_back
	add         $ACC0, $ACC1
call		send_back
	lsl16       $ACC0
call		send_back
	mrr         $AC1.M, $IX1
call		send_back
	xorc        $AC0.M, $AC1.M
call		send_back
; }

Unk_01a5:
; this is where result is written to main memory
; DSP mem 0x20-0x23 (8 bytes) are written back (DMA limitation),
; but only values @22 and @23 were modified (result is 32bit)
sr          @0x0023, $AC0.M
call		send_back
lr          $AX0.H, @0x0008	; CPU addr high
call		send_back
lr          $AX0.L, @0x0009	; CPU addr low
call		send_back
lri         $AX1.H, #0x0020	; DSP addr
call		send_back
lri         $AX1.L, #0x0008	; length
call		send_back
lri         $IX3, #0x0000	; there will be no iram DMA
call		send_back
call        0x808b			; DRAM->CPU <<<--- important!!
call		send_back
ret         
; }

; Free some space for the TROJAN CODEZ
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop         
;nop