;
;       Persona 2 Eternal Punishment (PSX) JAP / Custom Characters/Data Patch
;
;       Author: Sergey Shemet 06/10/2022

.psx



.definelabel SetDrawTPage,              0x800578fc
.definelabel storeColor,                0x8001c0b4
.definelabel initCopyCharChain,         0x8001b110
;.definelabel makeCharPixels,            0x8001a08f      ;need custom routine with custom font
;.definelabel GenerateSmallChar,         0x8001a284      ;need custom routine
.definelabel MakeShadowSmallChar,       0x8001b2a8
.definelabel PrintBigDMAText,           0x8001a3a8

.definelabel MyAddr,                    0x8009


.open "SLPS_028.25", 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,a0

        lhu v0,0x0(a0)              ;read half 2 bytes of text (a0, not s1+0c!!!!!)
        nop
       ; 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 s4,0x38(sp)
        move s4,a0                              ;textReadAddr - S4 (NOT S6!)
        sw s0,0x28(sp)
        move s0,a1
        sw s1,0x2c(sp)
        move s1,a2
        sw s3,0x34(sp)

;                                                   NEW COMMAND OBRAB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;lw v1,0x0(s5)
        ;nop
                ;v1/r3 - MyChars charcount
         andi v0,v0,0xff 
        addiu     s4,s4,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        a0,a3,0xff             ;s0 - cut textMode (color & shadow)
        lui         a3, 0x8008              ;a3 = 8008 0000
        lui         a2, 0xff00              ;a2 = FF000000

        addiu       t1,a3,-0x31a8         ;t1 = 8007b6d0 - new free CHAIN Here
        lw          v1, -0x31a8(a3)          ;r3/v1 = load freeChain
        lbu         a1,0x60(sp)             ;shadow flag from stack to a1
        lui         v0,0x8000               ;r2 = 8000 0000
        sw         ra,0x48(sp)
        sw         s7,0x44(sp)
        sw         s6,0x40(sp)
        sw         s5,0x3c(sp)                       ; push ra,r30,r23,31,r20
        sw         s2,0x30(sp)

        ;;init chains
        and         a2,v1,a2            ;a2 = r3 & ff000000 = FF000000
        andi        a1,a1,0xff         ;clean text mode (color/shadow)
        and         v1,v1,t0            ;r3 & 00ffffff
        or          s5,v1,v0            ;r20 - 80...+r3    = freeChain Main Addr
        lw         v0,0x4(t1)   ;Load DMA Counter
        lw         v1,0x0(s5)  ;r3 = next free Chain
        addiu      v0,v0,-0x1   ;DMA Counter-1
        and        v1,v1,t0     ; r3 & r8 (00ffffff) cut f.byte
        or         a2,a2,v1     ; a2 | r3 = ff+r3 = next free Chain (FF...) +
        sw         v0,0x4(t1)   ;save DMACounter
        jal storeColor
        sw        a2,-0x31a8(a3) ;SAVE next free Chain (FF...) to 7b6d0
        move       a0,s5       ;currentChainAddr
        sll        a1,s0,0x10    ;a1 = X<<10h (003A0000)
        sra        a1,a1,0x10   ; a1=a1>>10h 0000003A
        sll        a2,s1,0x10   ; a2 = Y << 10h
        jal        initCopyCharChain            ;init line chains  
        sra        a2,a2,0x10    ;a2>>10h - 100% clean coords
        ;move       a3,s0        ;store textMode _THIS IS FOR INIT

        ;;;;init ScratchPad
        ;;;;;;;;;;;;;;;;;;              CPU TO VRAM
        lui        a2,0x1f80  
        ori        a2,a2,0x348              ;a3 = FIRST CHAR START
        ;lui        a2,0x1f80               ;LOWER HALF OF CHAR - DONT NEED!!!
        ;ori        a2,a2,0x38c          


        ;4bit table pattern
       .include "EP_4bitPattern.asm"  


        li          v0,0x2
        sh          v0,0x1c(sp)
        li          v0,0xc
        li          a0,0x10                  ;COMMANDS IN CHAR FORMING CHAIN?
        lui         r3,0xa000                ;a0 = a000 0000
        sh          v0,0x1e(sp)             ; SAVE 000C0002 TO STACK+1c



        ;                           INIT CHAR
        lui         v0,0x100              ;FLUSH CACHE 01 00 00 00 =>DAT_1f80034b  

        sb         a0,0x3(a2)           ;SAVE 0d 00 00 00 =>DAT_1f80034c   cmdcount\
        sw         r3,0x4(a2);          SAVE a000000 TO DAT_1f80034c


        lui        at,0x1f80            ;scrathcpadStart
        sw         v0,0x388(at)         ;save 0x01 00 00 00  to end of 1st CHAR chain
             
       
        ; 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)

        lhu        a0,0x98(gp)          ;0310 ;Load x(0310) to r8 
        lhu        r3,0x9a(gp)          ;01f0 ;Load y(01F0)to r2       
        ;lui        v1,0x100             ;0100 0000 flushcache

        li         v0,0x80
        sb         v0,0x4(s3)
        sb         v0,0x5(s3)
        sb         v0,0x6(s3)           ;make 80 80 80 64 (3d4,5,6)


setY1:

       
        lw         v0,0x1c(sp)           ; r2 = 000c0002 from stack

        lh         a3,0x98(gp)                                      ;for futher sprite X calc
        sh         a0,0x18(sp)
        sh         r3,0x1a(sp)          ;SAVE CONCAT 013001f0 to stack

        lw         a0,0x18(sp)          ;LOAD 013001f0 from stack
        ;lw         v1,0x18(sp)          

        move       t0,a3
        sw         a0,0x8(a2)           ;DAT_1f800350  load a0 (upper coord 01f6) to a3+8 (DMA)
        sw         v0,0xc(a2)           ;=>DAT_1f800354  r2 - 000c0002 to 1st char (to a3+0c)
      
        bgez       a3,LAB_800194fc  
SetX1:
        sh        s1,0x20(sp)          ;store X half to sp+10 !!!!!!!!!!!!!!!!!
        addiu      t0,a3,0x3f 


LAB_800194fc:                                                    ;decoding coords for source sprite
        sra        v0,t0,0x6            ;r2 = a2 >> 6 = 4
        sll        v0,v0,0x6            ;r2 << 6 = 100
        subu       v0,a3,v0             ;r2 = a2 - r2 = 30
        lh         v1,0x9a(gp)          ;r3 = load Y half from mem
        sll        v0,v0,0x2            ;r2 << 2
        sb         v0,0xc(s3)                               ; >DAT_1f8003dc    ;STORE 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 CHAR SPRITE Y BYTE
        lhu        v1,0xa0(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

        sh         s0,0x8(s3)
        sh         s1,0xa(s3)

        li         v0,0xc                ; r2 = c     Sprite HEIGTH
        sh         v0,0x12(s3)            ; 3e2 - 000c save


        ;TEXT READ START



        lbu        a0,0x0(s4)              ;MAIN READ CHAR COMMAND - Load Byte Unsigned
        nop
        addiu     s4,s4,0x1                 ;Shift read address +1 byte

        ;;;;;;;;;;;;;;;;;;;;;;;;;CHAR CHECK CUTTED!

        lui        s6,0x8008               ;load 80080000 to r17
        addiu      s7,s6,-0x3198           ;r21 = r17-4930= 7b6d0 (tempDMA)
        lui        s0,0xff
        ori        s0,s0,0xffff            ;s0 = 00 ff ff ff
        lui        s1,0x8000               ;r3 = 8000 0000
NextChar:
        addiu       a0,a0,-0x20                 ;Shift unprintable symbols


                        ;ОБРАБОТКА ПРОБЕЛОВ

        bne a0,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


        ;ITS A SPACE!!!!
        sh v0,-0xE(t2)                  ;Save charcount += 1
        nop
        lbu        a0,0x0(s4)              ;LOAD NEXT CHAR
        ;j SpaceJump
       
        ;X COORD SHIFT (+6)
        lhu        v0,0xa8(gp)                  ;LOAD INIT X
        lhu        v1,0x8(s3)                   ;LOAD LAST X IN SCRATCH
        addiu      v0,v0,0x6                    ;v0 = INIT X+6
        addu       v1,v1,v0             ;LAST X = LAST X + (INIT X + 6)
        sh         v1,0x8(s3)           ;UPDATE LAST X IN SCRATCH DMA


        j NextChar
        addiu     s4,s4,0x1                 ;Shift read address +1 byte
        

SpaceCheckBranch:
;LAB_8001a608  NextChar: 
        jal        makeCharPixelsCustom    ;MAKE SMALL CHAR IN SCRATCH ___ CUSTOM ROUTINE
        clear     s2
                 ;               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       t6,s5      ; r14 = r21 (params)                      =r9 FROM SMALL SRC
        addiu      t5,sp,0x10  ; r11 = sp + 10 = 807ffe50
        lui        t3,0x8008
        addiu      t4,t3,-0x31a8                                       
        move       t1,s5      ; r9 = r21 (params again)     =t9        ;=r8 FROM SMALL


SetY:
     ;   sh         s8,0xa(s3)  ; DAT_1f8003da   *r19(1st scr DMA)+0a = r30 (Y??)    !!!!!!!!!!!!!!!!
SetX:
      ;  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) !!!!!!!!!!!!!!!!
PageLoop:
        ;MAKING COPYSPRITE CHAIN
        lw         v0,-0x3198(s6);     r2 = *freeChainAddr
        nop
        and        a0,v0,t2    ;  a0 = r2 & ff00..
        and        v0,v0,s0    ;  r2 & 00FFFFFF
        or         a1,v0,s1    ; a1 = r2 or r23 (80000000) = 801ADF10
        lw         v0,0x4(s7)  ; CmdCounter    r2 = *7b6d0+4 = 705
        lw         v1,0x0(a1)  ; r3 = New Free ChainAddr
        addiu      v0,v0,-0x1  ; r2 -= 1 Counter Down
        and        v1,v1,s0    ; r3 & 00FFFFFF cut begin byte
        or         a0,a0,v1    ; a0 & r3 = ff......
        sw         v0,0x4(s7)  ; CmdCounter    save DMA Counter
        sw         a0,-0x3198(s6); freeChain     save new freeChain
        
CopyCmdFromScratch:
        ; CopyScriptChain copy from scratch
        lw         t9,0x0(s3) ;>DAT_1f8003d0               r14 = 04000000 - DMA Commands Count
        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         t9,0x0(a1)  ;                          *a1 = r14
        sw         t7,0x4(a1)   ;                         *a1+4 = r15
        sw         t8,0x8(a1)    ;                        *a1+8 = r24
        sw         t5,0xc(a1)     ;                       *a1+c = r13
        lw         t9,0x10(s3);>DAT_1f8003e0               r14 = 000c0008 - spritesize after copy
        nop
        sw         t9,0x10(a1)  ;                         *a1+10 = r14 - LAST COMMAND SAVE
                           ; t1 = t0 (small) !!!!
                           ; t4 = t1 (small) !!!!
        lw         v1,0x18(t1)                   ;r3 = *r9+18 (next param???)        
        lw         v0,0x0(a1)                   ; 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(a1)                   ;  *curChainAddr a1 = r2 (upd ..04 with ..FF04)
        lw         a0,0x18(t1)                  ;  a0 = *r8+18 (first chain addr?)
        nop
        lw         v0,0x0(a0)           ;         r2 = *a0 FIRST CHAIN LINK TO NEXT??
        and        v1,a1,s0                     ; r3 = a1 (cur chain) & 00FFFFFF
        and        v0,v0,t2                     ; r2 & FF000000
        or         v0,v0,v1                     ; r2 | r3 = last chain adr w 10&....
        sw         v0,0x0(a0)                   ; *a0 = r2 FIRST CHAIN NEXT ADDR???
        sw         a1,0x18(t1)  ;t0->t1         ;    a1 = *r8+18 curChainAddr
        lhu        v0,0x4(t6)   ;t1->t6         r2 = half (DMA params)+4 (charCounter)
        nop
        bne        v0,zero,NotFirstChar        ;     if CharCount<>0 then Goto...
        nop                     ;clear t0
        sw         a1,0x28(t1)  ;t0->t1        ;*curChain+28 = Set first Char Chain
        sw         t8,0xc(t6) ;t1->t6            ; Params+0c = save STORE COORDS to params
        ;sh         s2,0xe(t4) ;t1->t6             ;Params+0e = save half Y
NotFirstChar:

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


        lui        a1,0x1f80   ;;;;;;;;;;;;;;;;;;;;;;;ADDRESS OF CHAR HERe   ---> SLL CHARNUM, 6

        lw         v0,-0x31a8(t3);>8007b6d0_freeChain     r2 = *nextFreeChain
        ori        a1,a1,0x348                   ;        a1 | 1f800348 = Scratch CharData
        and        a0,v0,t2                      ;        a0 = r2 & FF000000 FFNEXTCHAIN
        and        v0,v0,s0                      ;        r2 & 00FFFFFF = 00XTCHAN
        or         a3,v0,s1    ;or (800...)  ;         a3 = r2 | r12 = nextChain & 80...
        move       a2,a3                        ;         a2 = a3 (nextChain)
        lw         v0,0x4(t4)                   ;         CmdCounter    r2 = DMA Counter
        lw         v1,0x0(a3)                   ;          r3 = New Free ChainAddr / currHeader Addr
        addiu      v0,v0,-0x1                   ;         r2 -= 1 Counter Down
        and        v1,v1,s0                     ;         r3 & 80.... commandCount / currHeader
        or         a0,a0,v1                     ;         a0 & r3 = ff......
        sw         v0,0x4(t4);>DAT_8007b6d4_CmdCounter    save DMA Counter
        andi       v0,a3,0x3                    ;         r2 = a3 & 3 (check destAddr MOD 4)
         sw         a0,-0x31a8(t3);>8007b6d0_freeChain     save new freeChain

       
        beq        v0,zero,Copy16Bytes          ;         if a3 MOD 4 = 0 then Branch
        addiu      v0,a1,0x40           ;T3 = 388!
                
                ;;;;;;;;;;;;;;;Copy from ScratchPad To Chain





CopyBy2Bytes:
        lwl        t9,0x3(a1)                   ;         if a3 mod4 <> 0 - копируем по 2 байта
        lwr        t9,0x0(a1);>DAT_1f800348
        lwl        t7,0x7(a1)
        lwr        t7,0x4(a1);>DAT_1f80034c
        lwl        t8,0xb(a1)
        lwr        t8,0x8(a1);>DAT_1f800350
        lwl        t5,0xf(a1)
        lwr        t5,0xc(a1);>DAT_1f800354  
        swl        t9,0x3(a2)
        swr        t9,0x0(a2)
        swl        t7,0x7(a2)
        swr        t7,0x4(a2)
        swl        t8,0xb(a2)
        swr        t8,0x8(a2)
        swl        t5,0xf(a2)
        swr        t5,0xc(a2)
        addiu      a1,a1,0x10
        bne        a1,v0,CopyBy2Bytes
        addiu     a2,a2,0x10
        j          last4BytesCopy
        nop
Copy16Bytes:
        lw         t9,0x0(a1);>DAT_1f800348               a1 - curScratchAddr,a2 -cur DMAAddr
        lw         t7,0x4(a1)
        lw         t8,0x8(a1)
        lw         t5,0xc(a1)
        sw         t9,0x0(a2)
        sw         t7,0x4(a2)
        sw         t8,0x8(a2)
        sw         t5,0xc(a2)
        addiu      a1,a1,0x10
        bne        a1,v0,Copy16Bytes
        addiu     a2,a2,0x10
last4BytesCopy:
        lwl        t9,0x3(a1)          ;                   r14 left = 2 bytes from *a1+3
        lwr        t9,0x0(a1);>DAT_1f800358               r14 right = 2 bytes from *a1
        nop
        swl        t9,0x3(a2)                  ;          *a2 = r14 left
        swr        t9,0x0(a2)                  ;          *a2+3 = r14 right
       
       
                ; linking DMA char+copysprite
                        
                        ; t0  (smallSRC) = t1 (HERE) !!!!          ;r8 = r9 !!!!!!!!!!!!!
                        ; t1  (smallSRC) = t6 (HERE) !!!!          ;r9 = r14 !!!!!!!!!!!!

        lw         v1,0x18(t1)                  ;         r3 = current DMACopySprite Chain
        lw         v0,0x0(a3)                  ;          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(a3)                   ;         *a3 = r2 saveCurChainCmd (10FFFFFF)

        lw         a0,0x18(t1)                 ;          a0 = r8+18h - cur CopySpriteCmd hdrAddr
        nop
        lw         v0,0x0(a0)                   ;         r2 = *a0 (04FFFFFF)
        and        v1,a3,s0                    ;          r3 = a3 & 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(a0)                   ;         *a0 = r2 = FullCommand With Link!!! 
                                                ;         (04..CharAddr) + SpriteCopyCommand
        sw         a3,0x18(t1)                 ;          *r8+18 = Last Char Chain!

        addiu      t1,t1,0x4                    ;         r8 (params) += 4 (shift params for NextPage)
        addiu      v0,t6,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


        ;X COORD SHIFT (+6)
        lhu        v0,0xa8(gp)                  ;LOAD INIT X
        lhu        v1,0x8(s3)                   ;LOAD LAST X IN SCRATCH
        addiu      v0,v0,0x6                    ;v0 = INIT X+6
        addu       v1,v1,v0             ;LAST X = LAST X + (INIT X + 6)
        sh         v1,0x8(s3)           ;UPDATE LAST X IN SCRATCH DMA


SpaceJump:
                        ;;;CharCount + Check
        lhu        v0,0x4(s5)                  ;       r2 = current charDMACount
        lui        t9,MyAddr
        addiu      v0,v0,0x1                   ;          a += 1
        sh         v0,0x4(s5)                  ;save DMAcounter to chain               
        
                
                                        ;DMA OVERFLOW CHECK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (8007b6d4)
        
        lw         v0,0x4(s7)                ;         CmdCounter    r2 = DMA Char Counter
        ;lhu        v1,-0xC(t9)                ;v1 = 8008fff4 = minimum cmd counter
        move v1,5               ;80cd0 /// 
        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        a0,0x0(s4)                       ;     load next Char to a0 (byte)
        
        sh        v0,-0xE(t3)                   ; store myCharCounter to MyAddr-E
        addiu      s4,s4,0x1                    ;Shift CharAddr

        bne      v0,v1,NextChar               ; if currentChar<>OverallChar - branch
        nop

TextEnd:
        clear      s2     
        lui        s3,0x8008
        addiu      s4,s3,-0x3198                 ;         r19 = 80080000, r21 = 7b6d0
        lui        s1,0xff                     ;          r17 = 00ff0000
        ori        s1,s1,0xffff                  ;        r17 & ffff = 00ff ffff
        move       s0,s5                       ;         r16 = r20 (currentTLineParam)
        clear      a1
PageTLoop:                                                   ;ALMOST FINISH!!!!
        li         a2,0x1                     ;   a2=1
        addu       s2,s2,a2                  ;  s2(Counter) += a2
        lui        v0,0x8000                  ;           r2 = 80000000
        lui        a0,0xff00                   ;          a0 = ff00 0000
        lw         v1,-0x3198(s3);>8007b6d0_freeChain     r3 = next free Chain (*7b6d0)
        lw         a3,0x9c(gp);>DAT_8007b234              a3 = someParam(почти DMA)gp+a4 = 34
        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,-0x3198(s3);>8007b6d0_freeChain     r2 = next free chain
        lw         v1,0x0(v1)                 ;           r3 = *r3 = last chain - made one more chain
        and        v0,v0,a0                    ;          a2 & ff000000
        and        v1,v1,s1                   ;           r3 & 00FFFFFF
        lw         a0,0x4(s4);>DAT_8007b6d4_CmdCounter    a0 = DMA Counter
        or         v0,v0,v1                    ;          r2 | r3
        sw         v0,-0x3198(s3);>8007b6d0_freeChain     new free chain addr add to *7b6b0
        addiu      a0,a0,-0x1                  ;          DMA Cunter =- 1
        sw         a0,0x4(s4);>DAT_8007b6d4_CmdCounter    Store DMA Count
        lw         a0,0x30(s0)                ;           a0 = *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,s2,0x2                  ;          r2 = s2<2
        bne        v0,zero,PageTLoop           ;           if not r2 then goto Loop
        clear     a1                           ;         a1 = 0
        move       v0,s5                     ;          r2 = DMAParamsMain
        
        lw         ra,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 "EP_charload.asm"

.include "charCalcs.asm"


;patching PrintCommandText

.org 0x8001d138
        ;jal 0x8001a3a8                 ORIG CALL
        jal ExternalPrint

.org 0x8001d0c4
        ;jal 0x8001a3a8                 ORIG CALL
        jal ExternalPrint



.org 0x8001bee0
        j ReturnCharsInString              ;custom routine
        ; j 0x8001beec

.org 0x8001bf08
        ; addiu sp,sp,-0x18                   ;Original Code
         ; sw ra,0x10(sp)
         j calcnextXCustom                     ;PATCHED
        nop                        



.close


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




;;.include "txtpatches.asm"       ;misc text patches

;                       COMPILE COMMAND: ./armips -temp 123_EP EP_main.asm