Files
Persona2-PSX-asm-sources/ep_ai_main.asm
2025-10-18 17:25:22 +05:00

245 lines
13 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; ===== ОСНОВНАЯ ФУНКЦИЯ ПЕЧАТИ =====
.org 0x80090000
ExternalPrint:
lhu v0,0x0(a0) ; Читаем 2 байта текста
nop
srl v1,v0,0xD ; Проверяем 13-й бит (система 1-байтовых символов)
bne v1,zero,MyPrintLineRoutine ; Если установлен - используем кастомную систему
clear v1
j PrintBigDMAText ; Иначе - оригинальная система печати
nop
; ===== КАСТОМНАЯ СИСТЕМА ПЕЧАТИ =====
MyPrintLineRoutine:
addiu sp,sp,-0x50 ; Сохраняем контекст
sw s4,0x38(sp)
move s4,r4 ; s4 = адрес текста для чтения
sw s0,0x28(sp)
move s0,r5 ; s0 = параметр X
sw s1,0x2c(sp)
move s1,r6 ; s1 = параметр Y
sw s3,0x34(sp)
; ===== ИНИЦИАЛИЗАЦИЯ ПАРАМЕТРОВ ТЕКСТА =====
andi v0,v0,0xff
addiu s4,s4,0x2 ; Сдвигаем указатель текста на +2 байта
lui s3,MyAddr
sw v0,-0x10(s3) ; Сохраняем счётчик байтов @ 8008fff0
sh zero,-0xE(s3) ; Очищаем счётчик символов @ 8008fff2
; ===== ИНИЦИАЛИЗАЦИЯ DMA ЦЕПОЧЕК =====
lui s3,0x1f80
ori s3,s3,0x3d0 ; s3 = 1f8003d0 - команда копирования спрайта в scratch
lui t0,0xff
ori t0,t0,0xffff ; t0 = 00FFFFFF (маска)
andi r4,r7,0xff ; Режим текста (цвет и тень)
lui r7, 0x8008 ; r7 = 80080000
lui r6, 0xff00 ; r6 = FF000000 (маска)
; ЗАГРУЗКА ЦЕПОЧКИ ФОРМИРОВАНИЯ СИМВОЛОВ
addiu t1,r7,-0x31a8 ; t1 = адрес цепочки формирования (8007ce58)
lw v1, -0x31a8(r7) ; v1 = текущая свободная цепочка формирования
lbu r5,0x60(sp) ; Флаг тени из стека
and r6,v1,r6 ; r6 = старшие байты цепочки (FFxxxxxx)
andi r5,r5,0xff ; Очищаем режим текста
and v1,v1,t0 ; v1 = младшие байты цепочки (00xxxxxx)
or s5,v1,v0 ; s5 = адрес текущей цепочки формирования (80xxxxxx)
; ОБНОВЛЕНИЕ СЧЁТЧИКА И ЦЕПОЧКИ
lw v0,0x4(t1) ; Счётчик команд DMA
lw v1,0x0(s5) ; Следующая свободная цепочка
addiu v0,v0,-0x1 ; Уменьшаем счётчик
and v1,v1,t0 ; Обрезаем старший байт
or r6,r6,v1 ; Объединяем с старшими байтами
sw v0,0x4(t1) ; Сохраняем счётчик
jal storeColor
sw r6,-0x31a8(r7) ; Сохраняем обновлённую цепочку
; ===== ИНИЦИАЛИЗАЦИЯ ЦЕПОЧКИ КОПИРОВАНИЯ =====
move r4,s5 ; Адрес текущей цепочки
sll r5,s0,0x10 ; Координата X
sra r5,r5,0x10
sll r6,s1,0x10 ; Координата Y
jal initCopyCharChain ; Инициализация цепочки копирования
sra r6,r6,0x10
; ===== НАСТРОЙКА SCRATCH PAD ДЛЯ DMA =====
lui r6,0x1f80
ori r6,r6,0x348 ; r6 = 1f800348 - начало данных символа в scratch
; ... (паттерны 4-bit и инициализация пропущены для краткости)
; ===== ОСНОВНОЙ ЦИКЛ ОБРАБОТКИ СИМВОЛОВ =====
NextChar:
addiu r4,r4,-0x20 ; Сдвигаем непечатаемые символы
; ОБРАБОТКА ПРОБЕЛОВ
bne r4,zero,SpaceCheckBranch
nop
lui t2,MyAddr
lh v0,-0xE(t2) ; Текущий счётчик символов
nop
lh t3,-0x10(t2) ; Общий счётчик символов
addiu v0,v0,1
beq v0,t3,SpaceCheckBranch ; Если последний символ - не обрабатываем пробел
nop
; ПРОБЕЛ - только сдвигаем позицию
sh v0,-0xE(t2) ; Обновляем счётчик
nop
lbu r4,0x0(s4) ; Следующий символ
; СДВИГ ПОЗИЦИИ X
lhu v0,0xa8(gp) ; Начальный X
lhu v1,0x8(s3) ; Текущий X в scratch
addiu v0,v0,0x6 ; Сдвиг на 6 пикселей
addu v1,v1,v0 ; Новый X
sh v1,0x8(s3) ; Обновляем в scratch DMA
j NextChar
addiu s4,s4,0x1 ; Следующий байт текста
; ===== ОБРАБОТКА НЕ-ПРОБЕЛЬНЫХ СИМВОЛОВ =====
SpaceCheckBranch:
jal makeCharPixelsCustom ; СОЗДАЁМ ПИКСЕЛИ СИМВОЛА В SCRATCH
clear s2
; ===== ФОРМИРОВАНИЕ КОМАНДЫ КОПИРОВАНИЯ SPRITE =====
PageLoop:
; ЗАГРУЗКА ЦЕПОЧКИ КОПИРОВАНИЯ SPRITE
lw v0,-0x3198(s6) ; Адрес свободной цепочки копирования (8007ce68)
nop
and r4,v0,t2 ; Старшие байты
and v0,v0,s0 ; Младшие байты
or r5,v0,s1 ; r5 = полный адрес цепочки (80xxxxxx)
; ОБНОВЛЕНИЕ СЧЁТЧИКА КОПИРОВАНИЯ
lw v0,0x4(s7) ; Счётчик команд копирования
lw v1,0x0(r5) ; Следующая свободная цепочка
addiu v0,v0,-0x1 ; Уменьшаем счётчик
and v1,v1,s0 ; Обрезаем старший байт
or r4,r4,v1 ; Объединяем
sw v0,0x4(s7) ; Сохраняем счётчик
sw r4,-0x3198(s6) ; Сохраняем обновлённую цепочку
; ===== КОПИРОВАНИЕ ИЗ SCRATCH В ЦЕПОЧКУ =====
CopyCmdFromScratch:
; Копируем команду DMA из scratch в цепочку
lw t9,0x0(s3) ; Количество команд (04000000)
lw t7,0x4(s3) ; Команда копирования спрайта (64808080)
lw t8,0x8(s3) ; Координаты XY на экране
lw t5,0xc(s3) ; CLUT и координаты текстуры
; СОХРАНЯЕМ В ЦЕПОЧКУ КОПИРОВАНИЯ
sw t9,0x0(r5) ;
sw t7,0x4(r5)
sw t8,0x8(r5)
sw t5,0xc(r5)
lw t9,0x10(s3) ; Размер спрайта после копирования
nop
sw t9,0x10(r5) ; Последняя команда
; ===== СВЯЗЫВАНИЕ ЦЕПОЧЕК =====
; СВЯЗЬ: ЦЕПОЧКА ФОРМИРОВАНИЯ → ЦЕПОЧКА КОПИРОВАНИЯ
lw v1,0x18(t1) ; Текущая цепочка формирования
lw v0,0x0(r5) ; Текущая команда копирования
lw v1,0x0(v1) ; Следующая цепочка формирования
and v0,v0,t2 ; Маска старших байтов
and v1,v1,s0 ; Маска младших байтов
or v0,v0,v1 ; Объединяем
sw v0,0x0(r5) ; Обновляем команду
; ОБНОВЛЯЕМ ССЫЛКУ В ЦЕПОЧКЕ ФОРМИРОВАНИЯ
lw r4,0x18(t1) ; Адрес цепочки формирования
nop
lw v0,0x0(r4) ; Текущая команда формирования
and v1,r5,s0 ; Адрес цепочки копирования
and v0,v0,t2 ; Маска старших байтов
or v0,v0,v1 ; Объединяем
sw v0,0x0(r4) ; Сохраняем обновлённую ссылку
sw r5,0x18(t1) ; Сохраняем текущую цепочку копирования
; ===== ПРОВЕРКА ПЕРВОГО СИМВОЛА =====
lhu v0,0x4(t6) ; Счётчик символов
nop
bne v0,zero,NotFirstChar ; Если не первый символ - пропускаем
nop
; ИНИЦИАЛИЗАЦИЯ ДЛЯ ПЕРВОГО СИМВОЛА
sw r5,0x28(t1) ; Устанавливаем первую цепочку символа
sw t8,0xc(t6) ; Сохраняем координаты в параметрах
NotFirstChar:
; ===== КОПИРОВАНИЕ ДАННЫХ СИМВОЛА ИЗ SCRATCH =====
lui r5,0x1f80
ori r5,r5,0x348 ; r5 = данные символа в scratch
lw v0,-0x31a8(t3) ; Следующая свободная цепочка формирования
and r4,v0,t2 ; Старшие байты
and v0,v0,s0 ; Младшие байты
or r7,v0,s1 ; r7 = адрес цепочки (80xxxxxx)
move r6,r7 ; r6 = адрес назначения
; ... (копирование данных пропущено для краткости)
; ===== СВЯЗЫВАНИЕ: ДАННЫЕ СИМВОЛА → КОМАНДА КОПИРОВАНИЯ =====
lw v1,0x18(t1) ; Текущая команда копирования
lw v0,0x0(r7) ; Текущие данные символа
lw v1,0x0(v1) ; Следующая команда копирования
and v0,v0,t2 ; Маска старших байтов
and v1,v1,s0 ; Маска младших байтов
or v0,v0,v1 ; Объединяем
sw v0,0x0(r7) ; Обновляем данные символа
; ОБНОВЛЯЕМ ССЫЛКУ В КОМАНДЕ КОПИРОВАНИЯ
lw r4,0x18(t1) ; Адрес команды копирования
nop
lw v0,0x0(r4) ; Текущая команда
and v1,r7,s0 ; Адрес данных символа
and v0,v0,t2 ; Маска старших байтов
or v0,v0,v1 ; Объединяем
sw v0,0x0(r4) ; Сохраняем обновлённую ссылку
sw r7,0x18(t1) ; Сохраняем текущие данные символа
; ===== СДВИГ ПОЗИЦИИ ДЛЯ СЛЕДУЮЩЕГО СИМВОЛА =====
lhu v0,0xa8(gp) ; Начальный X
lhu v1,0x8(s3) ; Текущий X
addiu v0,v0,0x6 ; Сдвиг на 6 пикселей
addu v1,v1,v0 ; Новый X
sh v1,0x8(s3) ; Обновляем
; ===== ПРОВЕРКА ЗАВЕРШЕНИЯ ТЕКСТА =====
lhu v0,0x4(s5) ; Счётчик символов DMA
lui t9,MyAddr
addiu v0,v0,0x1
sh v0,0x4(s5) ; Сохраняем
; ПРОВЕРКА ПЕРЕПОЛНЕНИЯ DMA
lw v0,0x4(s7) ; Текущий счётчик
move v1,5 ; Минимальный лимит
sltu v0,v0,v1 ; Проверяем переполнение
bne v0,zero,TextEnd ; Если переполнение - завершаем
; ПРОВЕРКА КОНЦА СТРОКИ
lui t3,MyAddr
lhu v0,-0xE(t3) ; Текущий символ
lhu v1,-0x10(t3) ; Общее количество символов
addiu v0,v0,0x1
lbu r4,0x0(s4) ; Следующий символ
sh v0,-0xE(t3) ; Сохраняем счётчик
addiu s4,s4,0x1 ; Сдвигаем указатель
bne v0,v1,NextChar ; Если не конец - продолжаем
nop
; ===== ЗАВЕРШЕНИЕ ОБРАБОТКИ ТЕКСТА =====
TextEnd:
; ... (восстановление контекста и завершение)