05 июля 2015

     ZX-Basic Compiler
            ZX-Basic Compiler,
          удивительно простой
      расширяемый кросс-компилятор

Paulo Silva (Nitrofurano/Conscience) 

   Моё  увлечение  -  разрабатывать разные
вещи  для  поддержки ретросцены. Тут ещё и
ностальгия и возможность наконец добраться
до компьютеров,которым не повезло с полно─
ценной поддержкой во время их выпуска. Ещё
я  всегда поражаюсь, как современные прог─
раммы  тормозят на новых компьютерах, хотя
мы могли делать даже более интересные вещи
на старом железе (на котором выросли), это
при всех его ограничениях.
   Поэтому  мне захотелось поучаствовать в
конкурсах  типа  MSXDev, CSSCGC(Crap game
compo) и т.п., причём CSSCGC особенно заи─
нтересовал, потому  что большинство тамош─
них, так сказать, "игр" писались с помощью
Boriel's ZX-Basic Compiler, где  можно ис─ 
пользовать синтаксис,очень похожий на всем
известный Sinclair ZX Spectrum Basic.
   Я попробовал  написать несколько экспе─
риментальных кусков кода (http://
nitrofurano.altervista.org/retrocoding/
zxspectrum ), потом  посылал некоторые на─
броски игр на CSSCGC (наверно, штук 5-6 за
3 года,точно не помню - но они приведены в
спискеhttp://www.boriel.com/wiki/en/
index.php/ZX_BASIC:Released_Programs ).

   Быстрый  старт - просто  набрать  кусок
кода в текстовом редакторе, скомпилировать
его консольной командой типа

zxb.py -tBa helloworld.zxb

(что создаёт файл .tap - см.
http://www.boriel.com/wiki/en/index.php/
ZX_BASIC:Zxb#Command_Line_Options ).

   ZX-Basic Compiler довольно удивил своей
совместимостью: он  весь написан на Python
(кроме ассемблерных библиотек дляZ80, ис─
пользуемых при кросс-компиляции) - лично я
работаю с ним под GNU/Linux. При этом мож─
но  создавать  свои библиотеки и использо─
вать встроенный  ассемблер, что  открывает
возможность того,что оригинальный разрабо─
тчик, Jose' Rodriguez (boriel),  и не пре─
дусматривал:компилировать под любое другое
железо на процессоре Z80.И что меня совсем
удивило,не только на форуме ZX-Basic доду─
мались  до этого, а ещё и Haroldo Pinheiro
(haroldoop) пользовался этим для разработ─ 
ки  под  Sega Master System  и  выкладывал
свои программы (http://www.smspower.org/
Homebrew/Index?q=$:Platform=SMS ).

   Я активно сижу на форуме ZX-Basic
(http://www.boriel.com/forum/
zx-basic-compiler/ ) и  вношу информацию в
ZX-Basic wiki (http://www.boriel.com/
wiki/en/index.php/ZX_BASIC ), чтобы разоб─
раться ещё больше и попытаться помочь про─
екту, который мне так нравится.
   Я занялся всякими железками на Z80
(http://www.boriel.com/wiki/en/index.php/
ZX_BASIC:Released_Programs#OTHER_HARDWARE)
и собираю информацию по ним, которая может
помочь  для  проекта (http://
www.boriel.com/wiki/en/index.php/
ZX_BASIC:Other_architectures ) - начал я с
MSX (мне надо знать  и как работают видео─ 
режимы  на  чипах V9958 и V9990 ), Mattel
Aquarius  и  консолей  типа Colecovision и 
SG-1000. 
   Поддержка этих железок довольно хитрая,
ведь мало того,что надо сделать библиотеки
для  их архитектурных особенностей (видео─
процессоры, звуковые процессоры,если такие
есть, раскладка памяти, порты ввода-вывода
и т.д.),так ведь ещё в большинстве случаев
надо компилировать в файл-образ ПЗУ,к чему
ZX-Basic Compiler был совершенно  не прис─ 
пособлен,поэтому приходилось в начале про─
граммы выделять каждой переменной конкрет─
ный адрес.
   Поскольку было понятно, что каждый ком─
пьютер или приставка имеет свой формат ле─
нты  или ПЗУ, я как пользователь GNU/Linux
написал  простой  скрипт  на bash, который
мог бы "перевести" скомпилированный бинар─
ник  в запускаемый  образ, а потом в конце
запустить  соответствующий эмулятор, чтобы
проверить результат.

   Когда  я увидел, что Jim Bagley написал
PacManicMinerMan  для  аркадного  автомата 
PacMan (в кросс-ассемблере, скорее всего в 
Pasmo ), я решил сделать что-то похожее на 
ZX-Basic Compiler. Я  долго  возился, пока 
Jim не объяснил мне, что такоеwatchdog, о 
котором я никогда не подозревал!:D - тогда
я раззадорился поддержать ещё больше арка─
дных машин на Z80 (http://www.boriel.com/
wiki/en/index.php/
ZX_BASIC:Released_Programs#Arcade_Systems
- сейчас их там, наверно, около 30 ).

   Среди  всего  прочего  была  и плата ZX
Evo, с которой было явно проще, потому что 
её  основная  прошивка  реализует  клон ZX
Spectrum. Библиотеки  для видеорежимов ATM 
Turbo 2+ просто  щёлкают режимы, палитру и 
память.

   Например,
zxatmshadow(%11101010,1)
устанавливает режим320x200, это реализуе─
тся в библиотеке вот таким кодом:

sub zxatmshadow(tvl as ubyte,tst as byte):
 asm
   ld a,(ix+7)
   and $01
   cp 0
   jp z,zxatmshadowclose
  zxatmshadowset:
   halt
;- Включить тен.порты и доступ к палитре: 
;- ld a,%10101011 ;;- 6912 screen,turbo 
;- ld a,%10100011 ;;- 6912 screen,noturbo 
;- ld hl,$2a53 ;;- out (c),a:ret в TR-DOS 
;- push hl 
;- jp $3d2f ;;- nop:ret в TR-DOS 
   ld a,(ix+5)
   ld bc,$bd77
   jp zxatmshadowoutdosend
  zxatmshadowoutdos:
   ld hl,$2a53;;- out (c),a:ret в TR-DOS
   push hl
   jp $3d2f;;- nop:ret в TR-DOS
  zxatmshadowoutdosend:
   call zxatmshadowoutdos
   jp zxatmshadowend
  zxatmshadowclose:
; Выключить теневые порты. 
;;- ld a,%10101011 ;;- 6912 screen,turbo 
;;- ld a,%10100011 ;;- 6912 screen,noturbo 
   ld a,(ix+5)
   ld bc,$ff77
   out (c),a
  zxatmshadowend:
 end asm
end sub

   Запись  12-битного цвета rgb (типа#C55
- Indian Red,в цвет номер3 ) будет выгля─
деть как
  zxatmpalettergb(3,$C55)
(но  значение  цвета  обрежется  до  6 бит
из-за ограничений железа)

sub zxatmpalettergb(tad as ubyte,
tvl as uinteger):'- формат: $RGB 12bit
 asm
   ld e,(ix+7)
   ld d,(ix+6)
   ld a,d
   and %10001000
   rr a
   rr a
   rr a
   ld b,a
   ld a,d
   and %00000100
   rl a
   rl a
   rl a
   or b
   ld b,a
   ld a,d
   and %01000000
   rl a
   or b
   ld b,a
   ld a,e
   and %00000100
   rl a
   rl a
   rl a
   rl a
   or b
   ld b,a
   ld a,e
   and %00001000
   rr a
   rr a
   or b
   ld b,a
   ld a,(ix+5)
   and %00001000
   or %00000001
   xor $FF
   ld c,a
   ld a,(ix+5)
   and %00000111
   out (c),a
   ld a,$ff
   ld c,a
   ld a,b
   xor $FF
   out (c),a
 end asm
end sub

   Причём,разумеется,библиотеки тоже можно
писать  на бейсике, или на смеси ассеблера
с бейсиком, как удобно программисту  и как
он умеет, и в зависимости от того, что де─
лает код и какая нужна скорость.
   Библиотеки  вставляются  через include
в главный модуль на ZX-Basic, например:

#include "library/zxatmshadow.zxbasic"

   И  вся  программа  компилируется  через
bash-скрипт, например:

rm exampleO1.scl
cp library/boot_zmakebas.bas boot.bas
zmakebas -r -o boot.B boot.bas
rm boot.bas
mctrd cscl exampleO1.scl
mctrd add boot.B exampleO1.scl -b -a 10
zxb.py --org=28672 exampleO1.zxbasic
mv exampleO1.bin exec1.C
mctrd add exec1.C exampleO1.scl
rm *.B *.C
wine /opt/wine/emulators/UnrealSpeccy/
               unreal.exe exampleO1.scl &

   Этот скрипт подготавливает  образ диска
со скомпилированной программой (и всем,что
ей нужно), а потом автоматически запускает
эмулятор с этим диском.

   Для токенизации бейсик-загрузчика испо─
льзуется  zmakebas. Файлboot_zmakebas.bas
выглядит так:

10 clear 28671:border 0:cls
20 randomize usr 15619:rem:load"a:exec1"
code 28672
30 randomize usr 28672

   Mctrd - это  консольная утилита для со─
здания образов.scl или .trd и копирования
файлов   в  них.  Всё  остальное - команды
bash. Даже  если  вы  незнакомы  с  Unix и 
bash, подобные  скрипты  можно легко напи─ 
сать для других операционных систем.

   Загрузчик  в  слайдшоу для IVP'2014 ATM
Turbo/ZX Evo gfx compo, которое  я  делал, 
работает  немного не так: всю основную ра─
боту  делает  токенизированный  бейсик  из
zmakebas,  а   компилированный  бейсик  из 
ZX-Basic  Compiler  только меняет экранный 
режим и выводит картинку. Слайдшоу исполь─
зует обычные 4-битные .bmp-файлы.

  -boot.bas (токенизируется в zmakebas ):

10 clear 28671:border 0:cls
11 randomize usr 15619:rem:load"a:amtm"
code 32768
20 let amnt=0:for i=0 to 2:
let amnt=(amnt*10)+(peek(32768+i)-48):
next i
21 let dltm=0:for i=4 to 7:
let dltm=(dltm*10)+(peek(32768+i)-48):
next i
22 randomize usr 15619:rem:load"a:setscO"
code 28672
30 for l=1 to amnt
31 let w$=str$(1000+l):let w$=w$(2 to)
32 out 65527,255:out 32765,24+0
33 randomize usr 15619:rem:load"a:"+w$
code 32768
34 randomize usr 28672
35 pause dltm
36 next l
37 goto 30

  - компилирующий bash-скрипт.sh:

rm slideshow_ipv2014_evolutiongfxcompo.scl
zmakebas -r -o boot.B boot.bas
mctrd cscl
  slideshow_ipv2014_evolutiongfxcompo.scl
mctrd add boot.B
  slideshow_ipv2014_evolutiongfxcompo.scl
  -b -a 10
# zxb.py -t --org=28672 setscreenO.zxbasic
zxb.py --org=28672 setscreenO.zxbasic
mv setscreenO.bin setscO.C
mctrd add setscO.C
  slideshow_ipv2014_evolutiongfxcompo.scl
cp amtm.txt amtm.C
mctrd add amtm.C
  slideshow_ipv2014_evolutiongfxcompo.scl
rm *.B *.C
a=1;for i in pics/*.bmp;do new=$(printf
 "%03d.C" ${a});cp ${i} ${new};let a=a+1;
 done
for i in *.C;do mctrd add $i
 slideshow_ipv2014_evolutiongfxcompo.scl;
 done
rm *.B *.C
xpeccy
  slideshow_ipv2014_evolutiongfxcompo.scl
#wine /opt/wine/emulators/UnrealSpeccy/ 
   unreal.exe
   slideshow_ipv2014_evolutiongfxcompo.scl

   (чтобы  скопировать  картинки  на образ
диска.scl,  используется  цикл  "a=1; for
i in pics/*.bmp;  do new=$(printf "%03d.C"
${a});cp ${i} ${new};let a=a+1; done", это
картинки в 4-битном .bmp-формате.)

  Одна из будущих целей Boriel's ZX Basic
Compiler- распространить  его  на  другие 
процессорные  архитектуры, кроме Z80: на 
6502, 8080, 6809, 6800и т.п. Это бы  сде─
лало  его  настоящим  многоцелевым  кросс-
компилятором. Задача непростая, так как он
много использует регистрIX,а архитектуры 
типа6502и8080не имеют такого регистра. 
Может  быть, кто-то  захочет сделать ветки
для этого или даже реализует мультиархите─
ктурную компиляцию?



Other articles:


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Similar articles:
Nuotrauka'tm 2001 results - The results of the component.
From the authors - the first issue of a new electronic newspaper "SHOKER".
Litstranichka - "horror" of the life of the Philological Faculty of Lviv National University. Franko.
Notes programmer - bug monitor debugger ZS Scorpion 256.

В этот день...   21 November