;
;       Persona 2 Innocent Sin (PSX) JAP / Custom Characters/Data Patch
;
;       Author: Sergey Shemet 12/10/2021

.psx



.definelabel SetDrawTPage,              0x800542cc
.definelabel storeColor,                0x8001b0c8
.definelabel initCopyCharChain,         0x8001a070
.definelabel makeCharPixels,            0x8001a08f      ;need custom routine with custom font
.definelabel GenerateSmallChar,         0x8001a284      ;need custom routine
.definelabel MakeShadowSmallChar,       0x8001a20c
.definelabel PrintBigDMAText,           0x80019300

.definelabel MyAddr,                    0x8009


.open "SLPS_021.00", 0x8000F800


.include "complex_strings_copy.asm"                 ;Make complex strings in battles

;;neeeeed to init 8008fff6 = min dma commands

.org 0x80090000
ExternalPrint:
        ;;;;;;;text routing test routine
        move r3,s3      
        move s3,r4

        lhu v0,0x0(s3)              ;read half 2 bytes of text (r4, not s1+0c!!!!!)
        move s3,r3
        srl v1,v0,0xD               ;;;;Check 13th bit (1byte system !!!)
        bne v1,zero,MyPrintLineRoutine
        clear v1
        j PrintBigDMAText
        nop

        ;;;;;;;;;;;;;;;;;MyPrintLineRoutine
MyPrintLineRoutine:
        addiu sp,sp,-0x50
        sw s6,0x40(sp)
        move s6,r4                              ;textReadAddr
        sw s1,0x2c(sp)
        move s1,r5
        sw s2,0x30(sp)
        move s2,r6
        sw s3,0x34(sp)
        clear r25                       ;CURRENT TEXT MODE


;                                                   NEW COMMAND OBRAB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;lw v1,0x0(s6)
        ;nop
                ;v1/r3 - MyChars charcount
         andi v0,v0,0xff 
        addiu     s6,s6,0x2              ;Moving text read pointer +2bytes
        

        
        lui s3,MyAddr
        sw v0,-0x10(s3)         ;store bytecounter @ 8008fff0 and clean charCounter (8008fff2) 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        lui         s3,0x1f80
        ori         s3,s3,0x3d0             ;s3 = 1f8003d0 - copysprite cmd in scratch
        lui         t0,0xff
        ori         t0,t0,0xffff            ;t0 = 00FFFFFF

        sw          s0, 0x28(sp)             ;save s0 in stack
        andi        s0,r7,0xff             ;s0 - cut textMode (color & shadow)
        move        r4,s0                  ;r4 = s0 (cutted color)
        lui         r7, 0x8008              ;r7 = 8008 0000
        lui         r6, 0xff00              ;r6 = FF000000

        addiu       t1,r7,-0x4930         ;t1 = 8007b6d0 - new free CHAIN Here
        lw          v1, -0x4930(r7)          ;r3/v1 = load freeChain
        lbu         r5,0x60(sp)             ;shadow flag from stack to r5
        lui         v0,0x8000               ;r2 = 8000 0000
        sw         ra,0x4c(sp)
        sw         s8,0x48(sp)
        sw         s7,0x44(sp)
        sw         s5,0x3c(sp)                       ; push ra,r30,r23,31,r20
        sw         s4,0x38(sp)
        ;;init chains
        and         r6,v1,r6            ;r6 = r3 & ff000000 = FF000000
        andi        r5,r5,0xff         ;clean text mode (color/shadow)
        and         v1,v1,t0            ;r3 & 00ffffff
        or          r20,v1,v0            ;r20 - 80...+r3    = freeChain Main Addr
        lw         v0,0x4(t1)   ;Load DMA Counter
        lw         v1,0x0(r20)  ;r3 = next free Chain
        addiu      v0,v0,-0x1   ;DMA Counter-1
        and        v1,v1,t0     ; r3 & r8 (00ffffff) cut f.byte
        or         r6,r6,v1     ; r6 | r3 = ff+r3 = next free Chain (FF...) +
        sw         v0,0x4(t1)   ;save DMACounter
        jal storeColor
        sw        r6,-0x4930(r7) ;SAVE next free Chain (FF...) to 7b6d0
        move       r4,r20       ;currentChainAddr
        sll        r5,s1,0x10    ;r5 = X<<10h (003A0000)
        sra        r5,r5,0x10   ; r5=r5>>10h 0000003A
        sll        r6,s2,0x10   ; r6 = Y << 10h
        sra        r6,r6,0x10    ;r6>>10h - 100% clean coords
        jal        initCopyCharChain            ;init line chains  
        move       r7,s0        ;store textMode _THIS IS FOR INIT

        ;;;;init ScratchPad
        ;;;;;;;;;;;;;;;;;;              CPU TO VRAM
        lui        r7,0x1f80  
        ori        r7,r7,0x348              ;r7 = FIRST CHAR START
        ;lui        r6,0x1f80               ;LOWER HALF OF CHAR - DONT NEED!!!
        ;ori        r6,r6,0x38c          
        li          v0,0x2
        sh          v0,0x1c(sp)
        li          v0,0xc
        
        lui        r4,0xa000                ;r4 = a000 0000
        sh          v0,0x1e(sp)             ; SAVE 000C0002 TO STACK+1c



        ;                           INIT CHAR
        li          r5,0x10              ;cmd count 10 00 00 00 =>DAT_1f80034b  
        sb         r5,0x3(r7)           ;SAVE 0d 00 00 00 =>DAT_1f80034c   cmdcount\
        sw         r4,0x4(r7);          SAVE a000000 TO DAT_1f80034c
        lhu        t0,0xa0(gp)          ;0310 ;Load x(0310) to r8 
        lhu        v0,0xa2(gp)          ;01f0 ;Load y(01F0)to r2       
        lui        v1,0x100             ;0100 0000 flushcache
        lui        at,0x1f80            ;scrathcpadStart
        sw         v1,0x388(at)         ;save 0x01 00 00 00  to end of 1st CHAR chain
setY1:
        move       s8,s2                ;                 r18 to r30 (y)            !!!!!!!!!!!!!!!!!!!
        lh         r5,0xa0(gp)                                      ;for futher sprite X calc
        sh         t0,0x18(sp)
        sh         v0,0x1a(sp)          ;SAVE CONCAT 013001f0 to stack
        lw         r4,0x18(sp)          ;LOAD 013001f0 from stack
        lw        v0,0x1c(sp)           ; r2 = 000c0002 from stack
        sw         r4,0x8(r7)           ;SAVE 013001f0 TO SCRATCH
        sw         v0,0xc(r7)           ;=>DAT_1f800354  r2 - 000c0002 to 1st char (to r7+0c)

        lui        v0,0x8001            ;load 80010000 to r2
        
        ;4bit table pattern
       .include "4bitPattern.asm"  

        ; Copy Sprite DMA Command Forming
         li         v0,0x4
        sb         v0,0x3(s3)           ; 04 00 00 00 to 3d0 (sb 04 to 3d3) CHAIN LENGTH
        li         v0,0x64
        sb         v0,0x7(s3)           ;sb 64 to 3d7 (copySpriteCommand)
        li         v0,0x80
        sb         v0,0x4(s3)
        sb         v0,0x5(s3)
        sb         v0,0x6(s3)           ;make 80 80 80 64 (3d4,5,6,7)
        bgez       r5,LAB_800194fc  
SetX1:
        sh        s1,0x20(sp)          ;store X half to sp+10 !!!!!!!!!!!!!!!!!
         addiu      t0,r5,0x3f  
LAB_800194fc:                                                    ;decoding coords for source sprite
        sra        v0,t0,0x6            ;r2 = r6 >> 6 = 4
        sll        v0,v0,0x6            ;r2 << 6 = 100
        subu       v0,r5,v0             ;r2 = r6 - r2 = 30
        lh         v1,0xa2(gp)          ;r3 = load Y half from mem
        sll        v0,v0,0x2            ;r2 << 2
        sb         v0,0xc(s3)                    ; >DAT_1f8003dc    ;STORE RECT SRC CHAR SPRITE X BYTE
        bgez       v1,LAB_80019520      ;if Y r3>=0 - branch & r2=r3
        move      v0,v1
        addiu      v0,v1,0xff           ;else r2 = ff - r3
LAB_80019520:
        sra        v0,v0,0x8
        sll        v0,v0,0x8
        subu       v0,v1,v0 
        sb         v0,0xd(s3)                    ; >DAT_1f8003dd    ;STORE RECT SRC CHAR SPRITE Y BYTE
        lhu        v1,0xa8(gp)
                                          ;DIFF BETWEEN VERSs::::::::::::::::::::::
        li         v0,0x8                 ; r2 = 8     Sprite WIDTH
        sh         v0,0x10(s3)            ; 3e0 - 0008 save
        sh         v1,0xe(s3);=>DAT_1f8003de        ; *3de = r3 = 7df3         CLUT of RECT
        li         v0,0xc                ; r2 = c     Sprite HEIGTH
        sh         v0,0x12(s3)            ; 3e2 - 000c save

        ;TEXT READ START
        lbu        r4,0x0(s6)              ;MAIN READ CHAR COMMAND - Load Byte Unsigned
        nop
        addiu     s6,s6,0x1                 ;Shift read address +1 byte
        ;;;;;;;;;;;;;;;;;;;;;;;;;CHAR CHECK CUTTED!
        lui        s1,0x8008               ;load 80080000 to r17
        addiu      s5,s1,-0x4930           ;r21 = r17-4930= 7b6d0 (tempDMA)
        lui        s0,0xff
        ori        s0,s0,0xffff            ;s0 = 00 ff ff ff
        lui        s7,0x8000               ;r3 = 8000 0000
NextChar:
        addiu       r4,r4,-0x20                 ;Shift unprintable symbols

               

        li t2, 0xa0  ; минимальное значение оптимизированного кода (a0+20 = 192 (Русская А))
        sltu v0,r4,t2
        bne v0, zero, NotOptimized  ; проверяем на русский текст и перепрыгиваем на старый режим, если нет.
        nop

.include "main_spritecopy.asm"


NotOptimized:


                        ;ОБРАБОТКА ПРОБЕЛОВ
        
        bne r4,zero,SpaceCheckBranch    ;Если не пробел - перепрыгиваем сразу
        nop

        lui t2,MyAddr
        lh v0,-0xE(t2)                  ;Load my temp CHAR COUNTER for check
        nop
        lh t3,-0x10(t2)
        addiu v0,v0,1                   ;overall chars+1
        beq v0,t3,SpaceCheckBranch        ;is last char - пробел не проверяем!
        nop

        sh v0,-0xE(t2)                  ;Save charcount += 1
        lbu        r4,0x0(s6)              ;LOAD NEXT CHAR
        nop
        j NextChar
        addiu     s6,s6,0x1                 ;Shift read address +1 byte
        

SpaceCheckBranch:

        

        jal        makeCharPixelsCustom    ;MAKE SMALL CHAR IN SCRATCH ___ CUSTOM ROUTINE
        clear     r18

                 ;               Coords XY init
        lw         v0,0xb0(gp); =>DAT_8007b240_parms load r2 from r28+0b0 (7b240)(Xoffs)
        lui t2,MyAddr
        lh v1,-0xE(t2)                  ;Load my temp CHAR COUNTER for check
       ; lhu        v1,0x4(r20) ; current char = r3 = half *DMAAddr + 4
        addiu      v0,v0,0x6   ; 0x06 * 6px btw letters!
        
        
        mult       v1,v0       ; r3*r2 = xOffs*charNum



        lui        t2,0xff00   ; r10 = ld upper ff00 = ff000000
        move       t4,r20      ; r12 = r20 (params)
        addiu      t3,sp,0x10  ; r11 = sp + 10 = 807ffe50
        move       t1,r20      ; r12 = r20 (params again)
GetY:
        sh         s8,0xa(s3)  ; DAT_1f8003da   *r19(1st scr DMA)+0a = r30 (Y??)    !!!!!!!!!!!!!!!!
GetX:
        lhu        t5,0x20(sp) ; r13 = ld half (sp+20) = 003A ---X from sp+20 !!
        mflo       t6          ; r14 = lo
        addu       v0,t5,t6    ; r2 = r13 + r14 = X + Offset
        sh         v0,0x8(s3)  ;DAT_1f8003d8      save r2 half to 1f8003d8 = X (3A) !!!!!!!!!!!!!!!!





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IF Mode is not 0 = load 2 to page counter 






PageLoop:
        ;MAKING COPYSPRITE CHAIN
        lw         v0,-0x4930(s1);     r2 = *freeChainAddr
        nop
        and        r4,v0,t2    ;  r4 = r2 & ff00..
        and        v0,v0,s0    ;  r2 & 00FFFFFF
        or         r5,v0,s7    ; r5 = r2 or r23 (80000000) = 801ADF10
        lw         v0,0x4(s5)  ; CmdCounter    r2 = *7b6d0+4 = 705
        lw         v1,0x0(r5)  ; r3 = New Free ChainAddr
        addiu      v0,v0,-0x1  ; r2 -= 1 Counter Down
        and        v1,v1,s0    ; r3 & 00FFFFFF cut begin byte
        or         r4,r4,v1    ; r4 & r3 = ff......
        sw         v0,0x4(s5)  ; CmdCounter    save DMA Counter
        sw         r4,-0x4930(s1); freeChain     save new freeChain
CopyCmdFromScratch:
        ; CopyScriptChain copy from scratch
               

contStandartDMA:
        lui         t6,0x500 ; set 4 commands in next chain
        nop
        sw         t6,0x0(r5)  ;                          set 5 commands
        nop
        lui         t6, 0xe100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ori         t6,0x0234  ;;;;;;;make changepage command in every command to standart
        sw         t6,0x4(r5)                   ;store it before all 6400000 command    
        
        addiu   r5,4            ;SHIFT DEST ADDR


        lw         t7,0x4(s3) ;>DAT_1f8003d4               r15 = 64808080 - CopySpriteCmd
        lw         t8,0x8(s3) ;>DAT_1f8003d8               r24 = 001500d1 - xy screen coords
        lw         t5,0xc(s3); >DAT_1f8003dc               r13 = 7fd3f0c0 (CLUT & tex coord page)
       
        sw         t7,0x4(r5)   ;                         *r5+4 = r15
        sw         t8,0x8(r5)    ;                        *r5+8 = r24
        sw         t5,0xc(r5)     ;                       *r5+c = r13
        lw         t6,0x10(s3);>DAT_1f8003e0               r14 = 000c0008 - spritesize after copy
        nop
        sw         t6,0x10(r5)  ;                         *r5+10 = r14 - LAST COMMAND SAVE

        addiu   r5,-0x4            ;SHIFT DEST ADDR MINUS
              
        
        clear r25                ;clearing r25 (reset current chars status)



       
        
        lw         v1,0x18(t1)                   ;r3 = *r9+18 (next param???)        
        lw         v0,0x0(r5)                   ; r2 = *cur New Chainaddr
        lw         v1,0x0(v1)                   ; r3 = *r3
        and        v0,v0,t2                     ; r2 & ff000000
        and        v1,v1,s0                     ;r3 & 00FFFFFF
        or         v0,v0,v1                     ;  r2 | r3 = 04FFFFFF - commands with FFFFFF
        sw         v0,0x0(r5)                   ;  *curChainAddr r5 = r2 (upd ..04 with ..FF04)
        lw         r4,0x18(t1)                  ;  r4 = *r8+18 (first chain addr?)
        nop
        lw         v0,0x0(r4)           ;         r2 = *r4 FIRST CHAIN LINK TO NEXT??
        and        v1,r5,s0                     ; r3 = r5 (cur chain) & 00FFFFFF
        and        v0,v0,t2                     ; r2 & FF000000
        or         v0,v0,v1                     ; r2 | r3 = last chain adr w 10&....
        sw         v0,0x0(r4)                   ; *r4 = r2 FIRST CHAIN NEXT ADDR???
        sw         r5,0x18(t1)  ;t0->t1         ;    r5 = *r8+18 curChainAddr


        lhu        v0,0x4(t4)   ;t1->t4         r2 = half (DMA params)+4 (charCounter)
        nop
        bne        v0,zero,NotFirstChar        ;     if CharCount<>0 then Goto...
        nop
        sw         r5,0x28(t1)  ;t0->t1        ;*curChain+28 = currentChainAddr
        sw         t8,0xc(t4) ;t1->t4            ; Params+0c = save half X              STORE COORDS

        clear v0    
       sb         v0,-0x1(r20) ;store first char offset for moving string (is first in new type)
       ;sh         v0,-0x8(t4) ;store first char offset for moving string (is first in new type)
        nop

        ;sh         s2,0xe(t4) ;t1->t4             ;Params+0e = save half Y
NotFirstChar:
        lui        r5,0x1f80   ;;;;;;;;;;;;;;;;;;;;;;;ADDRESS OF CHAR HERe   ---> SLL CHARNUM, 6

        lw         v0,-0x4930(s1);>8007b6d0_freeChain     r2 = *nextFreeChain
        ori        r5,r5,0x348                   ;        r5 | 1f800348 = Scratch CharData
        and        r4,v0,t2                      ;        r4 = r2 & FF000000
        and        v0,v0,s0                      ;        r2 & 00FFFFFF
        or         r7,v0,s7    ;t4->s7 (800...)  ;         r7 = r2 | r12 = nextChain & 80...
        move       r6,r7                        ;         r6 = r7 (nextChain)
        lw         v0,0x4(s5)                   ;         CmdCounter    r2 = DMA Counter
        lw         v1,0x0(r7)                   ;          r3 = New Free ChainAddr / currHeader Addr
        addiu      v0,v0,-0x1                   ;         r2 -= 1 Counter Down
        and        v1,v1,s0                     ;         r3 & 00FFFFFF cut commandCount / currHeader
        or         r4,r4,v1                     ;         r4 & r3 = ff......
        sw         v0,0x4(s5);>DAT_8007b6d4_CmdCounter    save DMA Counter
        andi       v0,r7,0x3                    ;         r2 = r7 & 3 (check destAddr MOD 4)

        lui        t3,0x1f80
        ori        t3,t3,0x388                  ;       Scratch DMAChain CharEndAddr

        beq        v0,zero,Copy16Bytes          ;         if r7 MOD 4 = 0 then Branch
        sw         r4,-0x4930(s1);>8007b6d0_freeChain     save new freeChain
                
                ;;;;;;;;;;;;;;;Copy from ScratchPad To Chain

CopyBy2Bytes:
        lwl        t6,0x3(r5)                   ;         if r7 mod4 <> 0 - копируем по 2 байта
        lwr        t6,0x0(r5);>DAT_1f800348
        lwl        t7,0x7(r5)
        lwr        t7,0x4(r5);>DAT_1f80034c
        lwl        t8,0xb(r5)
        lwr        t8,0x8(r5);>DAT_1f800350
        lwl        t5,0xf(r5)
        lwr        t5,0xc(r5);>DAT_1f800354  
        swl        t6,0x3(r6)
        swr        t6,0x0(r6)
        swl        t7,0x7(r6)
        swr        t7,0x4(r6)
        swl        t8,0xb(r6)
        swr        t8,0x8(r6)
        swl        t5,0xf(r6)
        swr        t5,0xc(r6)
        addiu      r5,r5,0x10
        bne        r5,t3,CopyBy2Bytes
        addiu     r6,r6,0x10
        j          last4BytesCopy
        nop
Copy16Bytes:
        lw         t6,0x0(r5);>DAT_1f800348               r5 - curScratchAddr,r6 -cur DMAAddr
        lw         t7,0x4(r5)
        lw         t8,0x8(r5)
        lw         t5,0xc(r5)
        sw         t6,0x0(r6)
        sw         t7,0x4(r6)
        sw         t8,0x8(r6)
        sw         t5,0xc(r6)
        addiu      r5,r5,0x10
        bne        r5,t3,Copy16Bytes
        addiu     r6,r6,0x10
last4BytesCopy:
        lwl        t6,0x3(r5)          ;                   r14 left = 2 bytes from *r5+3
        lwr        t6,0x0(r5);>DAT_1f800358               r14 right = 2 bytes from *r5
        nop
        swl        t6,0x3(r6)                  ;          *r6 = r14 left
        swr        t6,0x0(r6)                  ;          *r6+3 = r14 right
                ; linking DMA char+copysprite
                      
                       
        lw         v1,0x18(t1)                  ;         r3 = current DMACopySprite Chain
        lw         v0,0x0(r7)                  ;          r2 = current CharChainCommands
        lw         v1,0x0(v1)                   ;         r3 = *r3 (comNum+FFFFFF(nextLink))
        and        v0,v0,t2                    ;          r2 & FF.....
        and        v1,v1,s0                     ;         r3 & 00FFFFFF
        or         v0,v0,v1                    ;          r2 | r3 = 10FFFFFF(cmdNum&FF..)
        sw         v0,0x0(r7)                   ;         *r7 = r2 saveCurChainCmd
        lw         r4,0x18(t1)                 ;          r4 = r8+18h - cur CopySpriteCmd hdrAddr
        nop
        lw         v0,0x0(r4)                   ;         r2 = *r4 (04FFFFFF)
        and        v1,r7,s0                    ;          r3 = r7 & 00FFFFFF (Copying Cur Char Chain)
        and        v0,v0,t2                     ;         r2 & FF000000 (04000000) CmdCount
        or         v0,v0,v1                    ;          R2 | R3 = 04(cmd)..+CharChainAddr
        sw         v0,0x0(r4)                   ;         *r4 = r2 = FullCommand With Link!!! 
                                                ;         (04..CharAddr) + SpriteCopyCommand
        sw         r7,0x18(t1)                 ;          *r8+18 = Last Char Chain!
        addiu      t1,t1,0x4                    ;         r8 (params) += 4 (shift params for NextPage)
        addiu      v0,t4,0x8                   ;          r2 = r9+8 (shift first chain param for Page)
        sltu       v0,t1,v0                     ;         r2 = r8 < r2(r9+8) (first page pass)
        bne        v0,zero,PageLoop            ;          if r2<>0 (r8<r2) then goto Next Page Loop
        nop
                 


OptimizedSpriteCopyEnd:

                        ;;;CharCount + Check
        lhu        v0,0x4(r20)                  ;       r2 = current charDMACount
        nop
        addiu      v0,v0,0x1                   ;          a += 1
        sh         v0,0x4(r20)                  ;save DMAcounter to chain               
        nop

                
                                        ;DMA OVERFLOW CHECK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (8007b6d4)
        lui        t3,MyAddr
        lw         v0,0x4(s5)                   ;         CmdCounter    r2 = DMA Counter
        lhu        v1,-0xC(t3)                ;v1 = 8008fff4 = minimum cmd counter
        nop
        sltu       v0,v0,v1             ; v0 = v0 < V1 ?
        bne        v0,zero,TextEnd      ;if v0<>0 then Goto End Text (DMA OVERFLOW!!!!)
        nop




        ;lui        t3,MyAddr
        lhu        v0,-0xE(t3)                   ; r2 = charCount In string
        lhu        v1,-0x10(t3)                   ; r3 = My charOverAll In string
        addiu      v0,v0,0x1                   ;          a += 1
        lbu        r4,0x0(s6)                       ;     load next Char to r4 (byte)
        
        sh        v0,-0xE(t3)                   ; store myCharCounter to MyAddr-E
        addiu      s6,s6,0x1                    ;Shift CharAddr

        bne      v0,v1,NextChar               ; if currentChar<>OverallChar - branch
        nop
TextEnd:
        clear      r18     
        lui        s3,0x8008
        addiu      s5,s3,-0x4930                 ;         r19 = 80080000, r21 = 7b6d0
        lui        s1,0xff                     ;          r17 = 00ff0000
        ori        s1,s1,0xffff                  ;        r17 & ffff = 00ff ffff
        move       s0,r20                       ;         r16 = r20 (currentTLineParam)
        clear      r5
        clear r25                ;clearing r25 (reset current chars status)
PageTLoop:                                                   ;ALMOST FINISH!!!!
        li         r6,0x1                     ;   r6=1
        addu       r18,r18,r6                  ;  r18(Counter) += r6
        lui        v0,0x8000                  ;           r2 = 80000000
        lui        r4,0xff00                   ;          r4 = ff00 0000
        lw         v1,-0x4930(s3);>8007b6d0_freeChain     r3 = next free Chain (*7b6d0)
;;;;;;;;;;;;;;;;
        lw         r7,0xa4(gp);>DAT_8007b234              r7 = Texture page = 34
        beq        r25,zero, lastTextPageDefaul
        nop
        li         r7,0x3f                      ;IF MODE<>0 then TexturePage = 23F
;;;;;;;;;;;;;;;''
lastTextPageDefaul:

        and        v1,v1,s1                   ;           r3 & 00FFFFFF
        or         v1,v1,v0                    ;          r3 | r2 = 80.....
        sw         v1,0x30(s0)                ;           store last free ChAddr to DMAParams
        lw         v0,-0x4930(s3);>8007b6d0_freeChain     r2 = next free chain
        lw         v1,0x0(v1)                 ;           r3 = *r3 = last chain - made one more chain
        and        v0,v0,r4                    ;          a2 & ff000000
        and        v1,v1,s1                   ;           r3 & 00FFFFFF
        lw         r4,0x4(s5);>DAT_8007b6d4_CmdCounter    r4 = DMA Counter
        or         v0,v0,v1                    ;          r2 | r3
        sw         v0,-0x4930(s3);>8007b6d0_freeChain     new free chain addr add to *7b6b0
        addiu      r4,r4,-0x1                  ;          DMA Cunter =- 1
        sw         r4,0x4(s5);>DAT_8007b6d4_CmdCounter    Store DMA Count
        lw         r4,0x30(s0)                ;           r4 = *DMA params + 30 = Start Of DMA Chain
        jal        SetDrawTPage                ;          Set DRAW PAGE
        addiu      s0,s0,0x4                ;             r16 += 4 - Shgift DMAParams for next Page
        sltiu      v0,r18,0x2                  ;          r2 = r18<2
        bne        v0,zero,PageTLoop           ;           if not r2 then goto Loop
        clear     r5                           ;         r5 = 0
        move       v0,r20                     ;          r2 = DMAParamsMain
        
        lw         ra,0x4c(sp)
        lw         s8,0x48(sp)
        lw         s7,0x44(sp)
        lw         s6,0x40(sp)
        lw         s5,0x3c(sp)                       ;restoring regs from Stack
        lw         s4,0x38(sp)
        lw         s3,0x34(sp)
        lw         s2,0x30(sp)
        lw         s1,0x2c(sp)
        lw         s0,0x28(sp) 
       
        jr ra
        addiu sp,sp,0x50
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Chars / 2 Return Func

.include "charload.asm"

.include "charCalcs.asm"




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0x8001a7dc
;;;;;text patch for Text MOVING & OFFSET


              ;make branch videocomand reading


chainSpriteCheck:
        lbu v1,0x7(r5)
        li r27, 0xe1
        beq r27, v1, ShiftedCommandCheck
        nop
        j 0x8001a7e4            ;return
        nop

ShiftedCommandCheck:
        lbu v1,0xb(r5)          ;my new shifted sprite command
        li r27, 0x64
        beq r27, v1, ShiftedCommandCheck2
        nop
        lbu v1,0x7(r5)
        nop 
        j 0x8001a7e4            ;return
        nop

ShiftedCommandCheck2:
        lbu v1,0xb(r5)
        
goingback:
        j 0x8001a7e4            ;return
        nop








;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     0x8001aa8c
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;text patch for Text MOVING & OFFSET
getRightCoords:
;        lw r5, 0x28(t1)         ;get chain addr from params
        ;lhu r3, 0xc(t2)         ;get X from params

        lbu r4,0x7(r5)
        li r2,0xe1               ;if my new 5 commands?
        
        bne r2,r4,oldStyleCommand
        nop
        addiu r5,4
        
oldStyleCommand:
        lhu r2, 0x8(r5)         ;getting cur x (r5 is chain addr) --------!
        lhu r4, 0xe(t2) ;;getting Y from param
        subu r3,r3,r2       ; get X offset
        move r12,r3               ; Saving X offset in r12
        lhu r2, 0xa(r5)         ;getting cur y from chain       ----------!
        sll r3,r3,0x10          ;Shift r3 <<< 10 bits
        ;add  r2,r23                             ;add
        subu r2,r4,r2      ;get Y offset
        
        ;clear r23
returnToInnocence:
        j 0x8001aaa8                    ;continue!
        nop


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0x8001ab2c
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 


movesprite:
        lbu r2,0x07(r4)
        nop
        beq r2, t7, simpleSpriteCmd             ;if r2 == t7 = 64 
        nop
        beq r2, t6, simpleSpriteCmd             ;if r2 == t6 = 66 --simple move
        nop
        li r3, 0xe1
        beq r2, r3, IsThisMyChain            ;ReallyMyChain
        nop
        j exitmovesprite
        nop

ReallyMyChain:
        lbu r2,0x03(r4)
        li r3, 0x05
        beq r2, r3, IsThisMyChain
        nop
        j exitmovesprite
        nop

IsThisMyChain:
        lbu r2,0x0b(r4)
        nop
        beq r2, t7, notSimpleSpriteCommand      ;is this my E1 + 64?
        nop
        j exitmovesprite
        nop

notSimpleSpriteCommand:
       ; lbu t7,-0x1(t2)                ;get offset XY
        lhu r2,0x0c(r4)                 ;load cur sprite X
        sra t6, t7, 0x4                 ;shift 12 >> 4 = 1 pix (OR 0)
        addu r2,r2,t4           ;add chain offset 
        ;addu r2,r2,t6          ;adding myMainOffset X
        sh r2,0xC(r4)

        
        lhu r3,0xE(r4)
        andi t6, t7, 0xF        ;get Y offset
        addu r3,r3,t3
        ;addu r3,r3,t6         ;adding myMainOffset (1,2,0, etc...)
        addiu r3,r3,2

        sh r3,0xE(r4)
        nop
        j exitmovesprite
        nop

simpleSpriteCmd:
        lhu r2,0x8(r4)
        lhu r3,0xA(r4)
        addu r2,r2,t4
        addu r3,r3,t3
        sh r2,0x8(r4)
        sh r3,0xA(r4)
        nop
exitmovesprite:
        
        j 0x8001ab5c            ;EXIT TO MAIN routine

;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SET TEXT BRIGHTNESS

setTextBrightness:
        lbu r2,0x07(v1)
        nop
        beq r2, t1, simpleBright            ;if r2 == t7 = 64 
        nop
        beq r2, t0, simpleBright             ;if r2 == t6 = 66 --simple move
        nop
        li r15, 0xe1
        beq r2, r15, ItsMyBrigth1            ;ReallyMyChain
        nop
        j exitbrightsprite
        nop


ItsMyBrigth1:
        lbu r2,0x0b(v1)
        nop
        beq r2, t1, ItsMyBrigthMake      ;is this my E1 + 64?
        nop
        j exitbrightsprite
        nop

ItsMyBrigthMake:
        sb s1,0x8(v1)
        sb s2,0x9(v1)
        sb s3,0xa(v1)
        j 0x8001ad6c
        nop

simpleBright:
        sb s1,0x4(v1)
        sb s2,0x5(v1)
        sb s3,0x6(v1)

exitbrightsprite:
        j 0x8001ad6c
        nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        ;Patching main code
.org 0x8001a7dc
        ;lbu v1,0x7(r5)         ;- ORIGINAL load current command
        j chainSpriteCheck
        nop

.org 0x8001aa8c
        ;lhu r2, 0x8(r5)         ;getting cur x (r5 is chain addr) --------!
        ;lhu r4, 0xe(t2) ;;getting Y from prarm param
        j getRightCoords
        nop

.org 0x8001ab2c
        ;lbu v0,0x07(a0)
        j movesprite            ;movingsprite routine
        nop


.org 0x8001ad48
        ;lbu v0,0x07(a1)
        j setTextBrightness            ;textbrightness routine
        nop
.close


;;;;;;;;;;;;;;;;;;;;;;;;; BOSSNAMECOPY
;.include "battle_patch.asm"




.include "txtpatches.asm"       ;misc text patches

;                       COMPILE COMMAND: ./armips -temp 123 main.asm