=======================
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г