PSX и Assembler |
Недавно меня вдруг приспичило познать, что же такое кодинг под консоли. Проблем с выбором приставки под которую я собирался программировать не было, ею стала - PSX. Давным давно, когда я был маленьким и у меня не было компьютера, я любил играть в игры. Сначала в NES затем и в PSX. На PSX я познал такие игры как Twisted Metal, Resident Evil, Dino Crisis, Duke Nukem, Red Alert, Parasite Eve и т.д. Всех больше мне приглянулся TM4, в который до сих пор играю, правда на эмуляторе. Еще тогда я мечтал создать свою игру, но отсутствие компьютера препятствовало этому делу. Теперь вернемся к современности. Недавно закачал Twisted Metal 2 и поиграл. Всплакнув от нахлынувших воспоминаний решил пощупать приставку поглубже( я не извращенец ). Данная статья является скорее переводом, но информация взята из разных источников. Начнем с первого появления приставки на прилавках магазинов. В Японии дата 3 декабря 1994, в США 9 сентября 1995, а в Европе 29 сентября 1995 года. Разработала приставку компания Sony. Краткие технические характеристики: CPU( Central Processing Unit ): Процессор MIPS R3000A совместимый с ( R3051 ) 32-разрядный RISC, тактовая частота 33.8688 MHz. Произведен LSI Logic Corp по лицензированной технологии у SGI. Чип содержит Geometry Transformation Engine и Data Decompression Engine. Geometry Transformation Engine Устройство добавляющее инструкции, которые необходимы при работе с трехмерной графикой. Возможности: - 360 000 полигонов в секунду. - 180 000 текстурированных и освещенных полигонов в секунду. Data Decompression Engine Устройство для декомпрессии изображений и видео, поддерживает MJPEG и H.261 файлы. GPU( Graphics Processing Unit ): Чип для работы с двухмерной графикой. Возможности: - максимум 16.7 миллионов цветов. - от 256x224 до 640x480 разрешения экрана. - максимум 24 бита на пиксел. - текстурирование и Гуро-затенение. - максимум 4000 8x8 спрайтов. SPU( Sound Processing Unit ): - 24 канала частотой до 44.1 Khz. Память: - главное ОЗУ 2 Мб. - видео ОЗУ 1 Мб. - звуковое ОЗУ 512 Кб. - буффер CD-ROM 32 Кб. - размер BIOS 512 Кб. - карта памяти вмещает 128 Кб. CD-ROM: - скорость чтения 300 кб/c. Ассемблерные инструкции: Описание регистров: - $zero ----- $0 ( всегда 0 ) - $at ----- $1 - $v0–$v1 ----- $2–$3 - $a0–$a3 ----- $4–$7 - $t0–$t7 ----- $8–$15 - $s0–$s7 ----- $16–$23 - $t8–$t9 ----- $24–$25 - $k0–$k1 ----- $26–$27( зарезервированы для ядра ) - $gp ----- $28( глобальный указатель ) - $sp ----- $29( указатель стека ) - $fp ----- $30( указатель фрейма ) - $ra ----- $31( адрес возврата ) Структура: cmd arg, ... // Пояснения. xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - 32 битный код команды - ADD - сложение двух операндов и запись в результат. С учетом знака. add a, b, c // a = b + c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0000 - ADDU - сложение двух операндов и запись в результат. Без учета знака. addu a, b, c // a = b + c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0001 - ADDI - сложение двух операндов и запись в результат. С учетом знака. addi a, b, c // a = b + c; a, b - регистры, c - значение. 0010 00bb bbba aaaa cccc cccc cccc cccc - ADDIU - сложение двух операндов и запись в результат. Без учета знака. addiu a, b, c // a = b + c; a, b - регистры, c - значение. 0010 01bb bbba aaaa cccc cccc cccc cccc - AND - побитовое and. and a, b, c // a = b & c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0100 - ANDI - побитовое and. andi a, b, c // a = b & c; a, b - регистры; c - значение. 0011 00bb bbba aaaa cccc cccc cccc cccc - BEQ - условный переход. Если операнды равны. beq a, b, offset // если ( a == b ) переход на offset; a, b - регистры, offset - адрес. 0001 00aa aaab bbbb oooo oooo oooo oooo - BGEZ - условный переход. Если операнд больше или равен 0. bgez a, offset // если ( a >= 0 ) переход на offset; a - регистр, offset - адрес. 0000 01aa aaa0 0001 oooo oooo oooo oooo - BGEZAL - условный переход. Если операнд больше 0. Сохранение адреса возврата в $31. bgezal a, offset // если ( a >= 0 ) переход на offset; a - регистр, offset - адрес. 0000 01aa aaa1 0001 oooo oooo oooo oooo - BGTZ - условный переход. Если операнд больше 0. bgtz a, offset // если ( a > 0 ) переход на offset; a - регистр, offset - адрес. 0001 11aa aaa0 0000 oooo oooo oooo oooo - BLEZ - условный переход. Если операнд меньше или равен 0. blez a, offset // если ( a <= 0 ) переход на offset; a - регистр, offset - адрес. 0001 10aa aaa0 0000 oooo oooo oooo oooo - BLTZ - условный переход. Если операнд меньше 0. bltz a, offset // если ( a < 0 ) переход на offset; a - регистр, offset - адрес. 0000 01aa aaa0 0000 oooo oooo oooo oooo - BLTZAL - условный переход. Если операнд меньше 0. Сохранение адреса возврата в $31. bltzal a, offset // если ( a < 0 ) переход на offset; a - регистр, offset - адрес. 0000 01aa aaa1 0000 oooo oooo oooo oooo - BNE - условный переход. Если операнды не равны. bne a, b, offset // если ( a != b ) переход на offset; a, b - регистры, offset - адрес. 0001 01aa aaab bbbb oooo oooo oooo oooo - DIV - деление. $LO - записывается целый результат, $HI - остаток. div a, b // $LO = a / b, $HI = a % b; a, b - регистры. 0000 00aa aaab bbbb 0000 0000 0001 1010 - DIVU - деление. $LO - записывается целый результат, $HI - остаток. Без учета знака. divu a, b // $LO = a / b, $HI = a % b; a, b - регистры. 0000 00aa aaab bbbb 0000 0000 0001 1011 - J - прыжок. j offset // переход на offset; offset - метка. 0000 10oo oooo oooo oooo oooo oooo oooo - JAL - прыжок. Сохранение адреса возврата в $31. jal offset // переход на offset; offset - метка. 0000 11oo oooo oooo oooo oooo oooo oooo - JR - прыжок. Переход на адрес, указанный в регистре. jr a // переход на a; a - регистр. 0000 00aa aaa0 0000 0000 0000 0000 1000 - LB - запись байта из указанного адреса в регистр. lb a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1000 00bb bbba aaaa oooo oooo oooo oooo - LBU - запись байта из указанного адреса в регистр. Значение без знака. lbu a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1001 00bb bbba aaaa oooo oooo oooo oooo - LH - запись половины слова( 16 бит ) из указанного адреса в регистр. lh a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1000 01bb bbba aaaa oooo oooo oooo oooo - LHU - запись половины слова( 16 бит ) из указанного адреса в регистр. Значение без знака. lhu a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1001 01bb bbba aaaa oooo oooo oooo oooo - LUI - запись значения в регистр со двигом влево на 16 бит. lui a, b // a = ( b << 16 ); a - регистр, b - значение. 0011 1100 000a aaaa bbbb bbbb bbbb bbbb - LW - запись слова из указанного адреса в регистр. lw a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1000 11bb bbba aaaa oooo oooo oooo oooo - LWU - запись слова из указанного адреса в регистр. Значение без знака. lwu a, offset( b ) // a = память( b + offset ); a, b - регистры, offset - адрес. 1001 11bb bbba aaaa oooo oooo oooo oooo - MFHI - копирование содержимого $HI в указанный регистр. mfhi a // a = $HI; a - регистр. 0000 0000 0000 0000 aaaa a000 0001 0000 - MFLO - копирование содержимого $LO в указанный регистр. mflo a // a = $LO; a - регистр. 0000 0000 0000 0000 aaaa a000 0001 0010 - MTHI - копирование содержимого указанного регистра в $HI. mthi a // $HI = a; a - регистр. 0000 00aa aaa0 0000 0000 0000 0001 0001 - MTLO - копирование содержимого указанного регистра в $LO. mtlo a // $LO = a; a - регистр. 0000 00aa aaa0 0000 0000 0000 0001 0011 - MULT - умножение операндов и запись результата в $LO. mult a, b // $LO = a * b; a, b - регистры. 0000 00aa aaab bbbb 0000 0000 0001 1000 - MULTU - умножение операндов и запись результата в $LO. Без знака. multu a, b // $LO = a * b; a, b - регистры. 0000 00aa aaab bbbb 0000 0000 0001 1001 - NOOP - то самое. Ничего не делает. noop // Ничего. 0000 0000 0000 0000 0000 0000 0000 0000 - OR - побитовое or. or a, b, c // a = b | c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0101 - ORI - побитовое or. ori a, b, c // a = b | c; a, b - регистры, c - значение. 0011 01bb bbba aaaa cccc cccc cccc cccc - SB - запись байта из регистра в память. sb a, offset( b ) // память( b + offset ) = a; a, b - регистры, offset - адрес.. 1010 00bb bbba aaaa oooo oooo oooo oooo - SH - запись полуслова( 16 бит ) из регистра в память. sh a, offset( b ) // память( b + offset ) = a; a, b - регистры, offset - адрес.. 1010 01bb bbba aaaa oooo oooo oooo oooo - SLL - запись в регистр результата, получившегося сдвигом регистра на указанное значение влево. sll a, b, c // a = b << c; a, b - регистры, c - значение.. 0000 0000 000b bbbb aaaa accc cc00 0000 - SLLV - запись в регистр результата, получившегося сдвигом регистра на указанное значение влево. sllv a, b, c // a = b << c; a, b, c - регистры.. 0000 00cc cccb bbbb aaaa a000 0000 0100 - SLT - присваивание регистру 1 или 0. slt a, b, c // если( b < c ) a = 1 иначе a = 0; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 1010 - SLTI - присваивание регистру 1 или 0. slti a, b, c // если( b < c ) a = 1 иначе a = 0; a, b - регистры; c - значение. 0010 10bb bbba aaaa cccc cccc cccc cccc - SLTIU - присваивание регистру 1 или 0. Без знака. sltiu a, b, c // если( b < c ) a = 1 иначе a = 0; a, b - регистры; c - значение. 0010 11bb bbba aaaa cccc cccc cccc cccc - SLTU - присваивание регистру 1 или 0. Без знака. sltu a, b, c // если( b < c ) a = 1 иначе a = 0; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 1011 - SRL - запись в регистр результата, получившегося сдвигом регистра на указанное значение вправо. srl a, b, c // a = b >> c; a, b - регистры, c - значение.. 0000 0000 000b bbbb aaaa accc cc00 0010 - SRLV - запись в регистр результата, получившегося сдвигом регистра на указанное значение вправо. srlv a, b, c // a = b >> c; a, b, c - регистры.. 0000 0000 000c cccc bbbb baaa aa00 0110 - SUB - запись в регистр разности двух регистров. sub a, b, c // a = b - c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0010 - SUBU - запись в регистр разности двух регистров. Без знака. subu a, b, c // a = b - c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0011 - SW - запись слова из регистра в память. sw a, offset( b ) // память( b + offset ) = a; a, b - регистры, offset - адрес.. 1010 11bb bbba aaaa oooo oooo oooo oooo - XOR - побитовое xor. xor a, b, c // a = b ^ c; a, b, c - регистры. 0000 00bb bbbc cccc aaaa a000 0010 0110 - XORI - побитовое xor. xori a, b, c // a = b ^ c; a, b - регистры, c - значение. 0011 10bb bbba aaaa cccc cccc cccc cccc Я рассмотрел полностью только команду ADD, другие команды аналогичны например SUB, SUBI, SUBU, SBIU. Ссылки: Википедия Playstation Много чего вкусного |
|