Использование кросс-компилятора z88dk

Компьютер "Спринтер" http://sprinter.nedopc.org

Moderator: Shaos

User avatar
Vasil Ivanov
Doomed
Posts: 413
Joined: 11 Dec 2003 14:34

Post by Vasil Ivanov »

Shaos wrote:
Sayman wrote:
Shaos wrote:Мой пылится - с тех пор как он мне начал винт портить много лет назад, у меня к нему интерес резко упал - хотя можно и с дискетки грузится для быстрых тестов...

P.S. Более того - он у меня так в старый PC-шный корпус и засандален, который я ещё в 2004 году в штатах достал - и клава старая есть, и мыша, и монитор коммодоровский...
так а исправить проблему порчи винта? может проблема софтовая (версия доса или биоса, а может винт сам уже полумёртвый был, а может дело вообще в шланге иде)?
Я откатывался на старый BIOS/DSS и винт менял - всё равно портит...
А тестовую программку написать и протестить ? :) Ну типа, чтобы на ide-шину выдавать разные комбинации кодов и тестить их соответствие образцовым. Спаяй гирлянду светодиодов и повесь на ide-порт :)
А какое место на винте у тебя портиться, служебные области или область данных ?. Сравни (на ПК) имиджи свежеприготовленного и порченного винта.
Vasil Ivanov
vasil-i@yandex.ru
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Корневой директорий превращался в список нечитабельных иероглифов...
Я тут за главного - если что шлите мыло на me собака shaos точка net
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Re: Использование кросс-компилятора z88dk

Post by DimkaM »

Sayman wrote:...вообще, странный какой-то компилятор...
Более чем странный. Какой из языков он поддерживает я не знаю, но точно не Си.
Года четыре назад помучался с ним. Нужно было скомпилить fatfs. С наскоку не пошло, з88дк не понял некоторые конструкции. Что то поправил, скомпилилось без ошибок. Но неработало. Пришлось в эмуле просматривать чё к чему. Выяснил, что компилится неправильно, опять поправил исходник. В итоге то конечно заработала либа, но я плюнул.
Купил ИАР за 1000$, сунул ему исходник фатфс и он ВНЕЗАПНО скомпилился и заработал без всяких переделок. Причём бинарь вышел в полтора раза меньше. 16к(включая драйвера sd и hdd) против 25к.

п.с. Про покупку ИАРа этоя конечно загнул, очень-условно и очень-бесплатным пользуюсь.
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Post by Sayman »

а собирал под что? под спринтера? а либы где спринтеровые брал с "головофайлами"? поделись?
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Post by Sayman »

вот одна из тем про сравнение на msx разных компиляторов с разными тестами (попугаями). z88dk самый стрёмный, sdcc среднячок, но с костылями. Hi Tech C 7.5 под мс-дос самый крутой. но есть одно но - он под MS-DOS. а надо бы под венду, хотя, конечно, досбокс может спасти...
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Post by DimkaM »

Сорри, наверно не в тему написал.
Собирал под ZX-Evo.

Про сравнение си компилеров для z80.
Собирал жпег-либу(от того же ЭльмЧана) в иаре и в сдцц.
Бинарь от иара распаковывает жпеги быстрее.
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Post by Sayman »

Может кто погонять компилятор си по ссылке ниже?
в цпм он был слегка известен как microgenSF 5.17. это его кросс версия, вроде современная (автор прислал). раньше я его не видел, даже цпмную версию.
https://www.dropbox.com/s/6f3v8g5l3pwj7 ... e.zip?dl=0
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Re: Использование кросс-компилятора z88dk

Post by Sayman »

слегка обновлю тему и саму ветку. застойные явления не хороши.
собственно, многие знают, что для zx-evolution (или как ещё её называют pentevo) есть такая штука, как evosdk. посидел я над ним, почитал, подумал, попробовал. отложив в сторону основной проект я прикинул, а что если...кинуть к Спринтеру и этот сдк? но нет. логика работы самого сдк мне не сильно нравится. особенно по части кодогенерации. Я имею в виду то, что весь багаж процедур, занимающий около 9кб (там 8 с копейкой) погружается всегда и никак иначе. даже пустой пример их комплекта всегда занимает около 10кб (9кб того, что в либе и ещё сколько-то того. что нагадил сам sdcc). поскольку с sdcc я знаком плохо, да и большая часть народу всячески ненавидит версии 3.х.х (а 2.9 сильно не оптимальный), я решил расчехлить Hi-Tech C 3.09. Да, цпмный, ну и что. зато я с ним знаком. начал переписывать стоковые либы под спринтер. так же наковырял некоторые процедуры из исходников библиотек для z88dk (там хоть как то Спринтер был поддержан). Хотя почти все процедуры пришлось переписать даже от туда. Например, несколько некорректно (с моей точки зрения или я просто не понял всего) были реализованы всякие fputc, и другие подобные процедуры. про read, open и другие файловые процедуры можно сказать тоже самое. начал ковырятельства где то с пятницы прошлой недели. а может с четверга. не важно. в качестве ближайшей цели я поставил себе адаптацию примера из evosdk - sprites - демка с шариками на фоне статичной картинки. во вложении к посту как раз результат. он сильно отличается от того, что есть в примерах evosdk. например:
1. образец_1 (evosdk) после сборки занимает в памяти 224кб (там после сборки есть инфа о ресурсах).
1.1. Мой вариант везде занимает около 90кб.
2. Код образца_1 в любом случае не менее 10кб (скорей всего больше, т.е. либа напихает 9кб + код генерированный sdcc из main.c).
2.1. мой вариант по коду занимает всего 5.2кб со всеми включёнными процедурами/функциями из библиотеки + код "main.c".
3. Образец_1 не имеет file oi.
3.1. мой образец имеет. хотя тут спорный момент - есть универсальность - можно подгрузить любую фоновую картинку, палитру для фона, спрайт с шариками и палитра для шариков. Сборка всего проекта не требуется, достаточно подменить файлы. Но это сильно спорно, может оно и не нужно.
4. По данным образца_1, макс.кол-во шариков на кадр не должно превышать 22, якобы начинает тормозить. на деле ощутимые тормоза начинаются от 30 шариков. на 64х шариках уже почти слайд-шоу.
4.1. Мой обращей, без затупа и мерцания может выдать 118 шариков. дальше нужно думать с синхрой, т.к. некоторые шарики начинают "помигивать". Второй экран не использую (если честно, не разобрался как с ним работать). Хотя этот момент тоже спорны и не совсем честный, т.к. у спринтера есть аксель, у pentevo baseconf его нет. возможно, на tsconf будет быстрее, с его дма и кэшем.
Файлы данных - отражённые по вертикали бмп файлы, с откушенным заголовком. фоновая картинка (bgspr.spr) имеет размер 320на256, отдельно файл палитры - bgspr.act в формате BGRa (32 бита), 128 цветов (512 байт). Файл с шариками balls.spr. То же отражённый бмп без заголовка, но имеет размеры 64на16. Файл палитры balls.act, так же 128 цветов в том же формате.

для тех, у кого нет возможности просмотреть эту "демку", вот скриншот:

 Sprinter balls screenshot
Image

для сравнения - оригинальные шарики:

 evosdk balls screenshot
Image

Пока на работе и дёрнуть ролик с эмуля не могу - комп затупливает. может дома смогу.

Ещё отдельно хочу сказать пара слов про сравнение солида и хайтеха. Василий - сравнение крайне не уместное. Solid C это K&R стандарт. хайтех это ansi c. Хайтех умеет и понимает long, double, float, дерективы #asm/#endasm, union и многое другое. есть оптимизатор кода и пример закреплённый к посту весь собран с оптимизатором. хотя, при написании некоторых либ я тупанул и вкарячил лишние команды, хотя они не влияют на что-либо.
You do not have the required permissions to view the files attached to this post.
User avatar
Vasil Ivanov
Doomed
Posts: 413
Joined: 11 Dec 2003 14:34

Re: Использование кросс-компилятора z88dk

Post by Vasil Ivanov »

Sayman wrote:Ещё отдельно хочу сказать пара слов про сравнение солида и хайтеха. Василий - сравнение крайне не уместное. Solid C это K&R стандарт. хайтех это ansi c. Хайтех умеет и понимает long, double, float, дерективы #asm/#endasm, union и многое другое.
Да, солид си недописанный до современного (средне-современного) уровня. Используй тот компилятор, который тебе больше нравится и собирай на нем бинарники для спринтера. И все будут довольны.
Vasil Ivanov
vasil-i@yandex.ru
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Re: Использование кросс-компилятора z88dk

Post by DimkaM »

попробовал "HI-TECH Z80 C Compiler Release Notes for 7.80PL2"
бинарь генерит больше по объёму чем иар, но этот код работает ощутимо быстрее
некая тестовая программулина отрабатала
в иаре 2080миллионотактов,(495 байт бинарь)
в хайтеч 1650миллионотактов(779 байт бинарь)
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Re: Использование кросс-компилятора z88dk

Post by Sayman »

А я ИАРа так и не асилил. мутный он какой-то.
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Re: Использование кросс-компилятора z88dk

Post by DimkaM »

Sayman wrote:А я ИАРа так и не асилил. мутный он какой-то.
если ещё есть желание осилить, то почитай статейку в Info Guide #11
Правда статья сама в trd
Поэтому процитирую сюда(примерчики можно взять из архива выше):

 статейка

Code: Select all

рабочее название: Why F@CKING IAR does not work?

IAR 'из коробки' совершенно не подходит для Спекки и спектрумиста. 
В нём нет библиотек для Спектрума, он стоит бешеных денег, им не удастся скомпилировать бинарь одной строчкой в cmd,
и он не умеет генерировать tdr\tap\scl etc.

Но всё-таки попробуем его осилить.

С чего начать? Создадим директорию "IAR"  и скопируем в неё папку "z80" из архива с ИАРом.
Скачиваем свежий xlink.exe, с официального сайта IARа, в директорию "z80\bin\" .
Теперь создадим в директории "IAR" папочку с проектом "lesson1", а в ней директорию 'list' для всякого полезного мусора.

Скопируем дефолтный cstartup.s01 из ИАРа(\z80\iccz80\) в директорию со своим проектом. 
В нем нас интересует два момента, первый это начало бинарника, он же старт программы:
	ASEG
	ORG	0
Соответственно меняем на свой адрес, допустим ORG 0x6000:
	ASEG
	ORG	0x6000
Второй момент, запретим прерывания сразу после метки init_C:
init_C
	DI
	LD	SP,.SFE.(CSTACK-1)	; from high to low address
На этом изменения закончены.

Теперь нам нужно создать файл Lnk.xcl, пустой, в нем пропишем строчки:
-cZ80 //процессор, под который собираем
-Z(CODE)RCODE,CODE,CDATA0,CONST,CSTR,CCSTR=6000-BFFE //сегменты памяти с константами и кодом
-Z(DATA)INTVEC=BFFF-C000 //сегмент с таблицей для прерываний im2
-Z(DATA)DATA0,IDATA0,UDATA0,ECSTR,ALIGN8|8,CSTACK+200=C001-FFFF //сегменты стека, переменных и т.п.
-e_medium_write=_formatted_write //конфигурация printf/sprintf  
-e_medium_read=_formatted_read //конфигурация scanf/sscanf 
cstartup //линкуем наш стартап
-C ../z80/lib/clz80 //подключаем библиотеку, опция '-C' позволит нам прилинковать свой cstartup
-Fraw-binary //собрать чистый бинарь
-l list/cout.html
-o code.cou //имя бинарника
-xehinms //включим всё для полноты картины
Сохраняем, закрываем. Если что-то не понятно, то всегда можно заглянуть в документацию, там всё подробно описано.

Создадим файл main.c:
//тут всё банально
void main(void)
{
}

Создадим батник 'make_c.bat', опять же не поленитесь прочитать описание опций в документации: 
..\z80\bin\iccz80 -v0 -ml -uua -q -e -K -gA -s9 -t4 -T -Llist\ -Alist\ -I"../z80/inc/" main.c
..\z80\bin\az80 Cstartup.s01
..\z80\bin\xlink main -f Lnk.xcl 
del *.r01
И запустим его. У нас скомпилировался "голый" бинарь code.cou(если вы не забыли скачать свежий xlink), который можно загрузить и запустить с адреса 0x6000
Так же в папке list появился файл main.s01 с чистым асмом и файл cout.html с картой адресов, эти файлы могут пригодится для отладки.
При использовании оператора '?'(тернарную условную операцию) со сложными выражениями, очень рекомендую оптимизацию не выше 7(-s7 либо -z7), так как замечены баги.
Текущий проект будем использовать как шаблон.
Для создания образа дискеты можно воспользоватся утилитой trdtool, добавив в конец батника:
..\z80\bin\trdtool # test.scl
..\z80\bin\trdtool + test.scl boot.b
..\z80\bin\trdtool + test.scl code.cou

Нда, наблюдать чистый экран очень интересно.
Тут два варианта, писать всё на Си, либо создать библиотеку на асме. Рассмотрим первый вариант.

Скопируем шаблонный проект.
Нам нужны инициализация экрана, печать символа и статичная переменная с текущим адресом знакоместа:
#include <string.h>
#include <intrz80.h>
#include <stdio.h>
static union {char * w;char b[2];}scrxy;
void scr_init(char a){
	*((char *)0x5800)=a;
	output8(0xfe,a>>3);
	memcpy((void *)0x5801, (void *)0x5800, 32*24-1);
	scrxy.w=(void *)0x4000;
	*((char *)0x4000)=0;
	memcpy((void *)0x4001, (void *)0x4000, (unsigned int)256*192/8-1);
}
int putchar(int ch){
	switch(ch){
		case '\n':
			scrxy.b[0]+=32;
		case '\r':
			scrxy.b[0]&=0xe0;
			break;
		default:{
				char* s=(char*)((ch<<3)+0x3c00);
				unsigned char i=8;
				while(i--){
					*scrxy.w=*(s++);
					scrxy.b[1]++;
				}
			}
			scrxy.w-=0x07ff;
			break;
	}
	if(!scrxy.b[0]){
		if((scrxy.b[1]+=8)==0x58) scrxy.b[1]=0x40;
	}
	return 1;
}
void main(void){
	scr_init(0x07<<3);
	puts("Hello World!");
	while(1) printf("Keyboard scan: 0x%02X\r",input(0x00fe));
}
Комментировать код нет смысла, т.к. это типичная печаталка символов, наш putchar подменит собой библиотечный,
который используют puts, printf и т.п.

Что бы каждый раз это не компилировать, нужно скомпилировать исходник как библиотеку.
Удалите функцию main(), и переименуйте исходник в 'mylib.c'. Так же переименуем директорию проекта в 'mylib'.
Удалите из проекта все файлы, кроме 'mylib.c'. Создадим файл 'make_c.bat' и пропишем в него следующую строчку:
..\z80\bin\iccz80 -v0 -ml -uua -b -q -x -K -gA -z9 -t4 -T -Llist\ -Alist\ -I"../z80/inc/" mylib.c 
И запустим его, у нас скомпилировалась библиотека 'mylib.r01'.
Создадим заголовочный файл 'mylib.h' со строкой:
void scr_init(char a);
Теперь откроем файл 'Lnk.xcl' из нашего шаблонного проекта и перед строчкой "-C ../z80/lib/clz80" добавим
строку "../mylib/mylib". Должно получиться:
...
cstartup //линкуем наш стартап
../mylib/mylib //линкуем собственную библиотеку
-C ../z80/lib/clz80 //подключаем библиотеку ИАРа, опция '-C' позволит нам прилинковать свой cstartup.s01
...
Можно проверить нашу библиотеку создав новый проект и скомпилировав строчки:
#include <stdio.h>
#include <intrz80.h>
#include "../mylib/mylib.h"
void main(void){
	scr_init(0x07<<3);
	puts("Hello World!");
	while(1) printf("Keyboard scan: 0x%02X\r",input(0x00fe));
}
Функции IO обычно пишутся на асме, поэтому следующую функцию будем писать на нём.
Каждую функцию желательно оборачивать в модули, что бы при линковке цеплялись только используемые модули:
	MODULE mymod1
	...
	ENDMOD
	MODULE mymod2
	...
	ENDMOD
	MODULE mymod3
	...
	END		;последний, в файле, модуль заканчивается именно так, а не ENDMOD
	
Создадим, в проекте mylib, файл graf.s01, с кодом:
	MODULE	fast_set_pix
	PUBLIC	fast_set_pix,fast_set_pix_table
	RSEG	CODE
fast_set_pix	;http://zxdn.narod.ru/coding/zg1etud2.txt
	push bc
	push de
	ld l,c
    LD H,HIGH(fast_set_pix_table)
    LD D,HIGH(fast_set_pix_table)+2
    LD A,(DE)
    INC D 
    OR (HL)
    INC H
    LD H,(HL)
    LD L,A
    LD A,(DE)
    OR (HL)
    LD (HL),A
	pop de
	pop bc
	ret
	RSEG	ALIGN8
fast_set_pix_table
	DEFS 1024 
	ENDMOD
	
	MODULE	fast_set_pix_init
	PUBLIC	fast_set_pix_init
	EXTERN	fast_set_pix_table
	RSEG	CODE
fast_set_pix_init
	push bc
	push de
    LD HL,fast_set_pix_table+256
    LD DE,0x4000
GEN0 
	LD (HL),D  
    DEC H      
    LD (HL),E  
    INC H  
    INC D
    LD A,D
    AND 7
    JR NZ,LABEL
    LD A,E
    SUB 0xE0
    LD E,A
    SBC A,A
    AND -8
    ADD A,D
    LD D,A
LABEL
    LD A,D     
    SUB 88     
    JR NZ,$+3  
    LD D,A     
    INC L      
    JR NZ,GEN0 
    INC H
    LD A,128
GEN1
	LD (HL),E  
    INC H      
    LD (HL),A  
    DEC H      
    RRCA       
    JR NC,$+3  
    INC E      
    INC L      
    JR NZ,GEN1 
	pop de
	pop bc
	ret
	ENDMOD
	
	MODULE	little_set_pix
	PUBLIC	little_set_pix
	RSEG	CODE
little_set_pix
	ld a,c
	and 0x07		
	or 0x40	
	ld h,a
	ld a,c
	rrca
	rrca
	rrca
	ld l,a
	and %00011000	
	or h			
	ld h,a
	ld a,l
	ld l,e	
	rrca
	rr l
	rra
	rr l
	rra		
	rr l
	rra	
	rrca	
	rrca		
	and %00111000	
	xor %11111110
	ld (l2+1),a ;конечно так нельзя делать в либах
l2	set 0,(hl)
	ret
	END
Здесь у нас две типичные рисовалки точки, одна побыстрее, вторая покороче.	
Уточнить про параметры, при вызове функций, можно в документации, раздел "Assembly language interface".
Что бы не плодить библиотеки, будем собирать их в одну.
В новом файле с именем mylib.xlib запишем строчки:
fetch-modules graf.r01 mylib.r01
list-modules mylib.r01
quit 

После строчки 'quit' обязательно должна быть пустая строка, т.к. xlib ругается на отсутствующий EOF.
Это скрипт для сборщика библиотек, он объединит две либы в одну. 
Добавим в 'make_c.bat' строку компиляции graf.c и соберём либу в один файл. Батник будет выглядеть:
..\z80\bin\iccz80 -v0 -ml -uua -b -q -x -K -gA -z9 -t4 -T -Llist\ -Alist\ -I"../z80/inc/" mylib.c 
..\z80\bin\az80 -uu -b -v0 graf.s01
..\z80\bin\xlib mylib.xlib

Соответственно в заголовочный файл mylib.h добавьте: 
void fast_set_pix_init(void);
void fast_set_pix(unsigned char x,unsigned char y); 
void little_set_pix(unsigned char x,unsigned char y);
#ifdef FASTPIXEL
#define set_pix fast_set_pix
#define set_pix_init fast_set_pix_init
#else
#define set_pix_init()
#define set_pix little_set_pix
#endif

Теперь запустим батник и проверим библиотеку:
#include <math.h>
//#define FASTPIXEL
#include "../mylib/mylib.h"
void main(void){
	unsigned char x=0;
	scr_init(0x07<<3);
	set_pix_init();
	do{
		set_pix(x,(sin((double)x/20)*20+95));
	}while(++x);
}
На фоне вычислений даблов и синусов, быстрый и маленький пиксели практически не отличимые по скорости, только по размеру занимаемой памяти.

Ну и напоследок освоим прерывания(данный код не будет работать на машинах, у которых мусор на шине данных):
#include <intrz80.h>
unsigned int int_count=0;
interrupt[0] void myint(void){
	int_count++;
	output8(0xfe,((unsigned char)int_count&0x70)>>4);
}
C_task void main(void){
	load_I_register(0xbf);
	interrupt_mode_2();
	enable_interrupt();
}
Для ‘мусорных’ шин красивого решения я не знаю. 
Как вариант выделить сегмент памяти под таблицу прерываний(INTTABLE) и сегмент с ‘зеркальным’(0xbfbf,0x8181 и т.п.) адресом под JP:
-Z(CODE)RCODE,CODE,CDATA0,CONST,CSTR,CCSTR=6000-BEBD //сегменты памяти с константами и кодом
-Z(DATA)INTJP=BEBE-BEC0 //сегмент с JP для прерываний im2
-Z(DATA)DATA0,IDATA0,UDATA0,ECSTR,ALIGN8|8,INTTABLE|8,CSTACK+200=BEC1-FFFF //сегменты стека, переменных и т.п.
В проект mylib добавим myim2.s01, в котором разместим JP на обработчик прерывания, таблицу векторов и инициализацию:
	MODULE	my_im2
	PUBLIC	my_im2_init
	RSEG	INTJP
	DEFS 3
	RSEG	INTTABLE
	DEFS 257
	RSEG	CODE
my_im2_init
	di
	ld a,0xc3
	ld (SFB(INTJP)),a
	ld (SFB(INTJP)+1),de
	ld a,HIGH(SFB(INTTABLE))
	ld i,a
	inc a
	ld hl,SFB(INTTABLE)-1
tloop
	inc hl
	ld (hl),HIGH(SFB(INTJP))
	cp h
	jr nz,tloop
	im 2
	ret
	END
Строка компиляции в батнике:
...
..\z80\bin\az80 -uu -b -v0 myim2.s01
...
Строка в mylib.xlib:
...
fetch-modules myim2.r01 mylib.r01
...
Соответственно в mylib.h добавим:
extern void my_im2_init(void *);
И собственно пример использования:
#include <intrz80.h>
#include "../mylib/mylib.h"
unsigned int int_count=0;
interrupt void myint(void){
	int_count++;
	output8(0xfe,((unsigned char)int_count&0x70)>>4);
}
C_task void main(void){
	my_im2_init(myint);
	enable_interrupt();
}


прошу прощения за скомканность, не техничность и отсылы в документацию. Сроки были ограничены, журнал вот-вот в "тираж". Хотел отложить на потом, но АлонеКодер наседал. Поэтому что получилось, то получилось.

есть зачатки статьи про банкинг в иаре, но пока нет вдохновенья закончить
Sayman
Maniac
Posts: 223
Joined: 05 Oct 2009 19:44
Location: 212.164.105.5

Re: Использование кросс-компилятора z88dk

Post by Sayman »

Ну его нафиг, это иар. геморно сейчас опять всякие либы пилить, чё-то собирать под него. уже есть что нужно для старого хайтеха и для sdcc частично. этого хватает.