Итак, начнем.

По умолчанию 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
- - - Добавлено - - -

Нажмите на изображение для увеличения. 

Название:	main_pi.jpg 
Просмотров:	108 
Размер:	18.7 Кб 
ID:	67545

- - - Добавлено - - -

Нажмите на изображение для увеличения. 

Название:	main_pi1.jpg 
Просмотров:	105 
Размер:	20.4 Кб 
ID:	67546

- - - Добавлено - - -

Цитата Сообщение от Shiny Посмотреть сообщение
На cp/m HiTech-C программа работает, если поменять типы данных с int на long.
Так а почему на sdcc подругому? Меняем - и работает

И ещё вывод просто %d, а не %.4d.