Хм. надо сделать отдельный трэд "sdcc для чайников" xD
просто хочется разобраться самому, а не на готовом.
Вид для печати
Хм. надо сделать отдельный трэд "sdcc для чайников" xD
просто хочется разобраться самому, а не на готовом.
Шиня, ты напиши список внятных вопросов, что тебя волнует в SDCC.
Я попробую на них ответить. Ну конечно то, что знаю и понимаю.
Так и тебе и другим полезно будет.
Можно на основе их и сделать для кофейников статью или руководство.
- - - Добавлено - - -
https://github.com/salextpuru/sdcc-n...dcc-noinit.pdf
Здесь в разделах c 3 по 5 подробно описано как из исходников получается бинарь. Для SDCC вообще. Спроси что непонятно.
Что-то вышло замудрено.
сборка:
в итоге получаюКод:set PATH=d:\!!____________prj\SDCC\bin\;%PATH%
sdcc -mz80 --no-std-crt0 --code-loc 0x8000 --data-loc 0 pi.c
hexameter pi.ihx
pause
Как подпихнуть crt0.s ? и как его нужно изменить для печати? сов7 туплю.Код:?ASlink-Warning-Undefined Global '_putchar' referenced by module 'vprintf'
- - - Добавлено - - -
ага, на сайте CPC было решение:
putchar_zx.s
причем ассемблер так прост, что давится на rst 10hКод:;; FILE: putchar.s
;; Modified to suit execution on the Amstrad CPC
;; by H. Hansen 2003
;; Original lines has been marked out!
.area _CODE
_putchar::
_putchar_rr_s::
ld hl,#2
add hl,sp
ld a,(hl)
rst 16 ; call 0xBB5A
ret
_putchar_rr_dbs::
ld a,e
rst 16 ; call 0xBB5A
ret
сборка:
Тащемта, новые способы создания носителей не интересны, наверное можно взять appmake.exe из z88 или собрать scl/trd на ужясме.Код:set PATH=d:\!!____________prj\SDCC\bin\;%PATH%
sdasz80 -o putchar_zx.s
sdcc -mz80 --code-loc 0xA000 --data-loc 0 --no-std-crt0 putchar_zx.rel pi.c
hexameter pi.ihx
pause
Вот только непонятна инициализация печати:
которую приходится впихивать в загрузчик.Код:ld a,2
call $1601
Дальше смешнее. Вот исходник(pi.c):
Всё компилится, но при запуске печатается сплошное непотребство. На cp/m HiTech-C программа работает, если поменять типы данных с int на long.Код:#include <stdio.h>
int main()
{
int r[2800 + 1];
int i, k;
int b, d;
int c;
c=0;
for (i = 0; i < 2800; i++) {
r[i] = 2000;
}
for (k = 2800; k > 0; k -= 14) {
d = 0;
i = k;
for (;;) {
d += r[i] * 10000;
b = 2 * i - 1;
r[i] = d % b;
d /= b;
i--;
if (i == 0) break;
d *= i;
}
printf("%.4d", c + d / 10000);
c = d % 10000;
}
return 0;
}
Меняю так же, получаю фигувам.
http://nsn.fm/upload/iblock/940/9402...7e34a66380.jpg
В чем причина неясно - то ли сам накосячил, то ли в другом?
А что именно должно печататься и что печатается?
- - - Добавлено - - -
Можно отдельно скомпилировать файл для putchar и отдельно программу. Получить отдельно два *.rel файла и потом слиноковать их.
- - - Добавлено - - -
Я сейчас не дома. Приеду завтра домой и проверю твою прогу.
в идеале должно быть 31415927.
Итак, начнем.
По умолчанию printf() в SDCC вообще не печатает float-чисел.
Умолчательный crt0.s ни фига не подходит для ZX-SPECTRUM. Надо его чуть отрехтовать. Дело в том, что умолчательный crt0.s рассчитан на ПЗУ с адреса 0.
- - - Добавлено - - -
В общем, главная ошибка в том, что у тебя в алгоритме PI переполнение.
В SDCC int - 16битный. А у тебя сразу 2000 на 10000 множится. И вуаля - косяк.
Надо long int. И все работает. Но медленно.
Короче, работает так:
- - - Добавлено - - -Код:#include <stdio.h>
void pitest(){
long int r[2800 + 1];
long int i, k;
long int b, d;
long int c;
c=0;
for (i = 0; i < 2800; i++) {
r[i] = 2000;
}
for (k = 2800; k > 0; k -= 14) {
d = 0;
i = k;
for (;;) {
d += r[i] * 10000;
b = 2 * i - 1;
r[i] = d % b;
d /= b;
i--;
if (i == 0) break;
d *= i;
}
printf("%d", (int)(c + d / 10000) );
c = d % 10000;
}
}
int main(){
printf("Hello world\nOk.\n%u %i %d %f\nRunning PI test\nPI=",0xFFFF,0xFFFF,0xFFFF,1.123456);
pitest();
return 0;
}
Правильный crt0.s (ну более правильный) такой:
- - - Добавлено - - -Код:;--------------------------------------------------------------------------
; crt0.s - Generic crt0.s for a Z80
;--------------------------------------------------------------------------
.module crt0
.globl _main
.area _CODE
;; Reset vector
jp init
init:
;; Set stack pointer directly above top of memory.
ld sp,#0x0000
;; Initialise global variables
call gsinit
call _main
jp _exit
;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _CODE
_exit::
1$:
halt
jr 1$
.area _GSINIT
gsinit::
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
.area _GSFINAL
ret
PUTCHAR такой прекрасно работает (и \n тоже)
- - - Добавлено - - -Код:;; FILE: putchar.s
.area _CODE
_putchar::
_putchar_rr_s::
ld hl,#2
add hl,sp
ld a,(hl)
cp #10
jr nz,nocr
ld a,#13
nocr:
rst 16 ; call 0xBB5A
ret
ЧТобы все это собрать, надо сделать так. Так, конечно, коряво, зато все по шагам понятно:
- - - Добавлено - - -Цитата:
# Компилируем С-файл (получаем main.rel)
sdcc -Os -c -mz80 main.c
# Начальный загрузчик и putchar() (получаем crt0.rel и putchar_zx.rel)
sdasz80 -g -l -s -o crt0.rel crt0.s
sdasz80 -g -l -s -o putchar_zx.rel putchar_zx.s
# Получаем hex-файл (main.ihx) с помощью линковки rel-файлов
# Внимание! crt0.rel ДОЛЖЕН БЫТЬ первым в списке линкуемых rel-файлов
sdcc --code-loc 0x6000 --no-std-crt0 -mz80 -o main.ihx crt0.rel putchar_zx.rel main.rel
# 0x6000 = 24576 (Получаем бинарь из HEX-файла)
hex2bin -p 0 -s 0x6000 main.ihx
# Это просто утилита для получения TAP-файла из бинаря в бейсик-загрузчиком.
bin2tap -b -a 24576 -r 24576 main.bin
Вложение 67545
- - - Добавлено - - -
Вложение 67546
- - - Добавлено - - -
Так а почему на sdcc подругому? Меняем - и работает:)
И ещё вывод просто %d, а не %.4d.
ересь какая-то вышла.
печать неверная и прога валится при расчетах.
Да, точно. Надо %.4d. Иначе кусочки, начинающиеся с нулей будут теряться.
- - - Добавлено - - -
Но твой файл работает. Может прога "hexameter.exe" глючит? Я то в линукс собираю. hex2bin использую. Или SCL как-то не так создаётся?
- - - Добавлено - - -
ВРУ. Для печати ведущих нулей надо %04d
- - - Добавлено - - -
ну как бы там ни было - твои команды дают нормальный хекс. а потом может бин кривой или SCL ?