=======================
SDK-ver1 56к D:\M3\
компилятор с бейсика в код MIPS 12к D:\M3\COMPL\
дизасемблер2(новый) кода прошивки в рабочий бейсик 39к D:\M3\DISASM\
эмулятор2(быстрый) исполняет бейсик как код из прошивки 39к D:\M3\EMULM3\
все проги рабочие и проверены с исходниками на VB6
описание распознаных процедур в прошивке
=======================
Создан SDK комплект разработчика для написания программ
для плеера Explay M3 и аналогов.
Язык разработки: упрощенный бейсик
Среда разработки: Visual Basic 6 и выше
+ эмулятор команд MIPS3000 и особеностей плеера M3 (моя прога)
адреса в ОЗУ плеера М3
8С00.0000 загрузчик прошивки
8С01.0000 основная программа
АС00.0000 видеопамять
В000.0000 порты как ячейки памяти
комплект состоит из 4х программ: (d:\m3\) -рабочий каталог
1. Дизасемблер с машинного кода в ассемблер, псевдо-Си, исполняемый бейсик.
также может дизасемблировать с 5ю уравнями детализации и коментариями.
2. Эмулятор плеера, и среда разработки программ, включает в себя
набор функций выполняющие побитовые операции(которые сам бейсик не может),
запись и чтение из виртуального ОЗУ плеера, вывод на экран текста и графики
320х240 16 цветов, но выводится как на 480х240, (плеер сжимает до 320)
чтение и запись в порты пока не реализованы, но ведутся логи.
Здесь можно запускать некоторые дизасемблированные процедуры из прошивки
или писать _свои программы_ (!) на простом бейсике,
разрешенные переменные:
a0-a4 v0-v1 t0-t9 hi lo тип long 32 бита, знаковые.(регистры) и регистр z0=0
числа диапазоне -2^15..2^15 (integer) или в диапазоне -2^31..2^31 (long)
разрешенные команды:
1)арифметические (+,-,*,/) с регистрами или числом (integer)
2)присваивание r = (long) (две команды) и r = (integer) (одна команда)
3)запись и чтение регистров из памяти 4,2,1 байтов (со знаком или без)
если загружается байт -127..-1 то его старший бит (знак) копируется на 8-31
если загружается слово16 -32767..-1 то его старший бит (знак) копируется на 16-31
4)двоичные побитовые (|,&,^,~,>>,<<,>>A) с регистрами или числом (integer)
5)логические операции совмещенные с командами перехода
if(r1<>0)then goto m1 (>,>=,<,<=,=,<>)
if(r1=r2)then goto m1
if(r1<>r2)then goto m1
6)логические операции совмещенные с командами присваивания
r = iif(r1>r2,1,0) только 1 или 0 (slt*)
r1 = iif(r3=0,r2,r1) только r2 или сам себя, т.е ничего if(r3=0)then (r1=r2)
r1 = iif(r3<>0,r2,r1) только r2 или сам себя, т.е ничего if(r3<>0)then (r1=r2)
7)вызов других процедур: Call nameSub
8)безусловный переход: goto m2 'if(0=0)
блоки if-endif for-next пока использовать не рекомендуется
хотя компилятор может их преобразовать в конструкцию
--------------------------------------
if not(условие) then goto m3 'if(условие) then
блок операторов
m3: 'end if
--------------------------------------
r = 1 'for r = 1 to 10
m4:
блок операторов
r = r + 1
if(r<=10)then goto m4 'next r
--------------------------------------
но правильная работа не гарантирутся, т.к компилятор простой(пока что)
важно! один оператор - одна строка, метки на отдельной строке.
непосредственная запись в память: (адрес)=число , (пока) не поддерживается
только (регистр+число)=регистр
но компилятор может это транслировать в 2-4 команды (используя регистр at)
также можно вызывать известные функции прошивки: (подробно в описании)
печать строки на экран:
sub print_string(x,y,adrFont,color,adrString)
Ra0 = 1 'координата х
Ra1 = 10 'координата у
Ra2 = &H8C0F90C0 'адрес шрифта 16х32 4цвета (но рус буквы печат-ся др шрифтом)
Ra3 = &H25 'цвет точки и фона и контура
Rv0 = &H8C18A148 'адрес строки
save_Wd32 (Rsp + &H10), Rv0 ' передается в стеке+16
Call s8C020344
end sub
некоторые правила:
если вызывается процедура из процедуры
то необходимо сохранить регистр ra в стеке и перед возвратом восстановить
sub proc1
sp=sp+8
(sp+4)=ra
call proc2
ra=(sp+4)
sp=sp-8
exit sub
если используются регистры s0-s7 fp (не рекомендуется)
то их надо вначале сохранить в стеке и перед выходом восстановить.
=================================================================
3. Компилятор с простого бейсика в машинный код
все переходы относительные в диапазоне +-128к так что размер одной
процедуры с переходами ограничен 256к.
на выходе листинг с ошибками и сырым ассемблером и код *.em3
его можно вставлять в кит. шрифт JIANT**.BIN, заливать в плеер
и исполнять в плеере (если там стоит хакнутая прошивка от Xing)
4.Интерпретатор-отладчик
позволяет исполнять машинный код прямо из прошивки(вирт. ОЗУ)
от адреса1 до адреса2 или пошагово с логами обращений к портам,
просмотром регистров, памяти и тек. инструкции.
Здесь же можно предварительно посмотреть как будет исполнятся
самописная своя прога и проверить на ошибки компиляцию в код.
Все проги на VB6 с исходниками и могут расширятся и изменяться
по желанию. Кому что не ясно пишите мне в гостевую или на мыло.
PS: кому хотелось игрушки, читалки текстов, итд, можете уже писать сами:)
можно и эмулятор синклера написать, для него игр навалом. и исходники в
инете есть, надо только переписать это на простой бейсик и вывод на
экран исправить. и звук переделать на wav формат. Это реально.
================================================================
Числа. Знаковые (sign) и беззнаковые (unsign).
Особенности и ошибки. {инструкция-одна машинная команда.}
Числа в плеере бывают 5-ти видов
байт - 0..255 (0..#FF)
integer -32768..+32767 (#8000...#7FFF)
word16 0..65535 (0..#FFFF)
long -2^31..2^31-1 (8000.0000..7FFF.FFFF)
word32 0..2^32-1 0-#FFFF.FFFF
все непосредственные данные в инструкциях - integer
кроме побитовых &AND |OR ^XOR ~NOR - там word16
*инструкции имеют префикс imm или букву i на конце.
бейсик имеет только тип Integer и Byte поэтому
word16 приходится хранить в Long, но там значение
#8000-#FFFF автоматом расширяются до #FFFF.8000-#FFFF.FFFF
что привидит к ошибкам, поэтому Hex лучше хранить в string*4
val(&H8000) это val(&HFFFF8000) поэтому для перевода в десятичные
надо пользоваться формулой: байт1*256^3+байт2*256^2+байт3*256+байт4
32 битные числа могут быть знаковыми long и беззнаковыми word32
бейсик имеет только тип Long поэтому беззнаковые тоже там хранятся,
но значение посмотреть можно функцией Hex()
беззнаковые Hex8 лучше хранить в string*8
но для совместимости с плеером всё хранится в Long, а при выполнении
беззнаковых инструкций надо учитывать и обрабатывать через спец функции
эти инструкции имеют на конце модификатор - букву "u"
addu: r=r1+r2 (unsign) if r1<0 or r2<0 then r=addu32(r1,r2)
subu: r=r1-r2 (unsign) if r1<0 or r2<0 then r=subu32(r1,r2)
sltu: iff(r1< r2,1,0) (unsign) if r1<0 or r2<0 then r=sltu32(r1,r2)
multu: hilo=r1*r2 (unsign) if r1<0 or r2<0 then r=mult64u(r1,r2)
divu: lo=r1/r2 hi=r1%r2 (unsign) if r1<0 or r2<0 then r=div64u(r1,r2)
для знакового умножения можно пользоваться r=r1*r2 для небольших чисел,
а для больших знаковых, функцией r=mult64z(r1,r2)
с делением хуже, операции lo=int(r1/r2) : hi=r1 mod r2
для отрицательных чисел работают неправильно и как работает эта
инструкция в самом плеере надо выяснять тестированием!
addiu сначала расширяет знак в integer -> long, затем складывает как
беззнаковые word32 , хотя рез-т совпадает со знаковым сложением.
знаковый и беззнаковый результат разный только для чисел
8000..FFFF и 8000.0000..FFFF.FFFF , а для остальных одинаковый!
потому что отрицательное число это NOT+1 -1+1 FFFF+0001=1.0000
при знаковых операциях перенос 1 отбрасывается, в беззнаковых -нет.
Будьте внимательны при работе с беззнаковыми числами в бейсике
8000..FFFF и 8000.0000..FFFF.FFFF - могут быть ошибки.
В связи с этим ранние версии SDK могут работать с ошибками
в последней версии это частично исправлено, но не везде,
возможно еще есть ошибки из-за этих особенностей,
по идее надо каждую инструкцию описывать функцией, но тогда
работать будет медленно, хотя можно на ассемблере написать
и в DLL засунуть, но пока не охота.
16 февраля 2007г