Войти
ФлеймФорумЖелезо

Блеск и нищета 8/16-битных консолей и ПК (18 стр)

Страницы: 117 18 19 2045 Следующая »
#255
(Правка: 19:55) 19:55, 17 апр. 2018

Рассматривая исходники stdio Hisoft C на 8-битном ZX Spectrum.

Красиво оформлять любили уже тогда:

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*          HEADER           */
/*                           */
/* Copyright (C) 1984 Hisoft */
/* Last changed  15 Aug 1985 */
/*****************************/


Стековые переменные стоили дорого - косвенная адресация по регистру IX была медленее доступа к глобальной переменной, поэтому:

#define  FAST  static


Типа void в принципе не было, int всегда вменялся по умолчанию, если не указан char:

#define  void  int
/*  Forward declarations for non-int library functions  */
extern char *strcat(), *strncat(), *strcpy(), *strncpy(), *strchr(), *strrchr(),
            *strpbrk(), *calloc(), *malloc(), *sbrk(),    *fgets(),  *gets();


var_args был реализован по своему, видимо для упрощения:

/*  Two variadic arithmetic functions (see manual for details)  */
int max(param_byte_count)  auto
{
  static int argc, *argv, max;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  max  = -32767;

  while (argc--)
    {
      if (*argv > max) max = *argv;
      --argv;
    }

  return max;
}


Так же упрощен был парсер приведения типа через ключевое слово cast:

typedef  char * __char_ptr;
int peek(address)
{
  return  * cast(__char_ptr) address;
}
void poke(address, value)
{
  * cast(__char_ptr) address = value;
}


Встроенный асм тоже был упрощен донельзя - через ключевое слово inline( ... ) в память просто загонялись машкоды (как байты так и слова), причём для того чтобы сослаться на какие то переменные применялись разные трюки:

/*  Глобалки для ссылок из маш-кодов... */
unsigned  reg_hl, reg_de, reg_bc;
char      reg_a;

/*  Input and Output  */

/* В код зашиваются ссылки на глобалки */
int out(data, port)
{
  reg_bc = port;  reg_hl = data;
  inline(
    0x4BED, &reg_bc, /* ld bc,(reg_bc) */
    0x2A,   &reg_hl, /* ld hl,(reg_hl) */
    0x69ED);         /* out (c),l      */
}

/* Код берет данные из стека и возвращается из ф-ии поэтому сам */
int inp(port)
{
  inline(
    0xE1DD,     /* pop  ix    */
    0xE1,       /* pop  hl    */
    0xC1,       /* pop  bc    */
    0xE5,       /* push hl    */
    0x68ED,     /* in   l,(c) */
    0x26,   0,  /* ld   h,0   */
    0xC9);      /* ret        */
}


Вообще имеется куча дефайнов явно под упрощение написание инлайнов, но они в то же время не используются самой библиотекой, видимо для краткости:

#define LD_A_from  0x3A
#define LD_A_into  0x32
#define LD_A_with  0x3E
#define LD_HL_from 0x2A
#define LD_HL_into 0x22
#define LD_HL_with 0x21
#define LD_DE_from 0x5BED
#define LD_DE_into 0x53ED


malloc/free по умолчанию имеют в качестве кучи только 1000 свободных байт, потому что malloc опирается на функцию sbrk, которая реализована так:

#define HEAPSIZE 1000

char *sbrk(n)
  unsigned n;
{
  static char *p,
    heap[HEAPSIZE],
    *heap_ptr=heap;

  if (heap_ptr+n > heap+HEAPSIZE) return ERROR;
  p=heap_ptr;
  heap_ptr += n;
  return p;
}
Для увеличения размера кучи документация на полном серьезе предлагает модифицировать код функции sbrk "под себя".


Есть библиотечная поддержка 32-битных:

void long_add(c, a, b)
  char *a, *b, *c;
{
  static unsigned u, i;

  u = 0;
  for (i = 0; i < 4; ++i)
    {
      u   +=  *a++  +  *b++;
      *c++ =  u & 0xff;
      u  >>=  8;
    }
}


Для графики и звука дёргаются процедуры из ПЗУ бейсика:

cls()
{
  inline(0xCD,0xD6B);
}


Есть и наивности бурной юности следующего толка:

#define  FALSE   0 /* for Boolean operations */
#define  TRUE    1


#256
9:04, 18 апр. 2018


религия 16-ти ножек,...  да они больные на всю голову.

#257
14:54, 18 апр. 2018

=A=L=X=
> Hisoft C на 8-битном ZX Spectrum
Чё-то не понятно, этот компилятор только генерирует код для спектрума, или же умеет на нём работать?

#258
14:57, 18 апр. 2018

Panzerschrek[CN]
> этот компилятор только генерирует код для спектрума, или же умеет на нём
> работать?

Он на нём работает.  Для кросскомпиляции есть sdcc и z88dk.  Ну как можно не знать про Hisoft C и Hisoft PASCAL ?

#259
15:12, 18 апр. 2018

Panzerschrek[CN]
> Чё-то не понятно, этот компилятор только генерирует код для спектрума, или же
> умеет на нём работать?

Это полноценный компилятор под ZX Spectrum, он в ~26Кб RAM спектрума (из ~42Кб свободной для использования) размещал редактор и однопроходный компилятор. В оставшейся части памяти располагался текст программы и в неё так же компилировалась сама программа.
Я выше приводил выдержки из его stdlib, который шёл как отдельный файл на диске, например.
Структура редактирования была забавная - сразу после запуска включался режим компилятора. По комбинации кнопок можно было попасть в режим редактора.
В режиме редактора можно было редактировать программу в ОЗУ. Командой можно вернуться в режим компилятора.
Так вот - в режиме компилятора компилятор собственно ждал от пользователя ввода программы символ за символом прямо на экран. Как бы в консоль. И тут же её компилировал. Однопроходно.
Ввод в качестве очередной строки пустого инклюда:

#include
(без имени файла) приводило к тому, что содержимое программы из редактора начинало само как бы набираться на экране, то есть производилась её компиляция.
При этом встреча #include "имя_файла" приводила уже к загрузке и компиляции этого файла.
Была даже нестандартная директива
#list-
#list+
которая или выключала или включала обратно пропечатывание включаемого файла на экране.

#260
17:27, 18 апр. 2018

Жесть какая.
Кажется, что используя такой компилятор, многого не напишешь: в памяти весят компилятор и исходник, а значит на скомпилированный бинарник много места не останется.

#261
4:28, 19 апр. 2018

Panzerschrek[CN]
> Кажется, что используя такой компилятор, многого не напишешь: в памяти весят
> компилятор и исходник, а значит на скомпилированный бинарник много места не
> останется.

Да, много места не было, но всё было не так уж и плохо.
Кстати забыл еще что в этих ~26Кб была еще Runtime Library - такие функции как printf/scanf (и некоторые другие) были встроены и не требовали подключения заголовков.

На самом деле можно было прибегнуть к трюку с размещением кода на внешнем накопителе - тогда почти всё свободное место в памяти останется для скомпилированной программы.
Даже при использовании в качестве внешнего накопителя магнитофонной ленты Hisoft C использовал следующий трюк: когда мы сохраняем исходник из редактора на ленту он сохраняет его как серию бинарных фрагментов размером по 514 байт между которыми вставлялась 2-3-секундная пауза. При встрече #include "имя_файла" компилятор входил в режим загрузки - мы включали магнитофон в нужном месте и начинался процесс подгрузки-компиляции такими блоками, в 2-3 секунды между блоками компилятор более чем успевал скомпилировать очередной кусок кода. Получалось, что даже с неудобной магнитофонной лентой можно было хранить все исходники на кассетах и компилировать их "на лету", без полной загрузки в ОЗУ.
С дисководами ситуация, конечно, была еще проще.

#262
(Правка: 6:11) 6:10, 19 апр. 2018

Ничего у нас не получилось с Си на спектруме, тогда, в 1992 году. Но на Паскале написать тетрис таки удалось.

#263
(Правка: 7:55) 7:49, 19 апр. 2018

Dexus
> Ничего у нас не получилось с Си на спектруме, тогда, в 1992 году.

Это потому что не было на кассете скорее всего как раз хотя бы stdio.h с stdio.lib (последний по правильному должен был называться stdio.c, что справедливо для всех файлов такого типа из его поставки, это исходники всегда).
Был просто бинарник Си и видимо то же руководство на русском что была у меня. А в силу того, что в RTL не было почти ничего кроме sprintf/scanf/putc/getc, то даже змейку написать было невозможно - ей требовались аналоги inputkey и locatexy. А это всё было в stdio или нужно было шарить как самому повторить подобное (вызвать процедуру из бейсика):

_beep(DE,HL)
{
 static de,hl;

 de=DE;
 hl=HL;
 inline(0xdd,0xe5,
        0xed,0x5b,&de,
        0x2a,&hl,
        0xcd,0x3b5,
        0xdd,0xe1);
}

В результате - да, в отличие от Hisoft Pascal пиратская копия Hisoft C да еще на кассете не давала развернуться в полную силу начинающему программисту.
Если же говорить про версию для дисковода - тут всё еще богаче, на ней распространялись не только stdio.h/stdio.lib, но и несколько примеров программ разной степени сложности, например:

+ maths.lib

Насколько я понял, это интерфейс к движку чисел с плавающей точкой из ПЗУ с бейсиком в обратной польской нотации.

#264
11:48, 19 апр. 2018

=A=L=X=
> Это потому что не было на кассете скорее всего как раз хотя бы stdio.h с stdio.lib
Возможно да, я был еще мелкий, плохо помню причину :) Помню что бестолково всё было...

#265
(Правка: 13:47) 13:46, 19 апр. 2018

Скомпоновал много из написанного выше и немного нового в новую статью...

О музыке

Самый примитивный компьютерный звук извлекался из однобитового "спикера". Компьютер через порт ввода вывода или подавал или снимал постоянное напряжение на динамик. Звук таким образом в основе своей представлял серию щелчков. Программирование звуковых эффектов таким образом сводилось к периодической записи в порт спикера битов 0 или 1. Однако подавая эти биты с нужной частотой и в правильной последовательности можно было воспроизводить как монотонную ноту, так и довольно сложные комбинации. Например если выводить быстро подряд поочередно с небольшим интервалом две разные ноты, то они для слуха специфично сливались в некое подобие двухголосой полифонии, хотя никогда и не звучали одновременно. Плюс свою лепту могла внести физическая инерция динамика — если менять напряжение на нём достаточно часто, то он не будет успевать доходить до крайних положений, что может смягчить и обогатить звук.
"Однобитовую" музыку подобного плана можно послушать на примере музыкального редактора Wham! для 8–битного компьютера ZX Spectrum 48:

Причём Wham! позволял выгрузить музыку с воспроизводящим её кодом для использования в других программах — чем некоторые игры пользовались.
Но некоторые шли дальше и создавали на однобитовом звуке на этом же ZX Spectrum 48 почти невозможное звучание:

Конечно звук при этом получается очень "грязным", но сам факт такого звучания на однобитовом "подёргивании" спикера всё равно впечатляет.
Однако все эти методы воспроизведения музыки требовали от процессоров тех лет почти всё время заниматься высчитыванием пауз между записями в звуковой порт и собственно этими записями — свободного времени на игру, например, оставалось мало. А если прислушаться внимательно к мелодии выше из Wham!, где прямо во время воспроизведения скроллится нотный стан — то можно заметить, что ценой за это является заметная пауза между нотами. Поэтому в играх столь сложная полифония не использовалась — музыка воспроизводилась только в главном меню игры, а в самой игре звуковое оформление сводилось к щелчкам и попискиваниям при выстрелах и т.п.

Чтобы разгрузить центральный процессор инженеры IBM в IBM PC немного усовершенствовали схему — в этих (изначально) 16–битных ПК имелась микросхема Intel 8253 содержащая три независимых программируемых счётчика/таймера, третий из которых отсчитывая заданные интервалы автоматически "дёргал" спикер. Таким образом ЦП мог начать воспроизведение монотонного однобитового звука заданной частоты, а само воспроизведение в дальнейшем не требовало его участия (хотя надо было вмешаться позднее, чтобы звук остановить или изменить его тональность). Однако монофонический монотонный однобитовый звук впечатлить своими музыкальными возможностями никого не мог — требовалось что–то поинтереснее.

Решение напрашивалось само — сделать микросхему с несколькими "голосами" и не однобитовыми, а с настраиваемой громкостью и даже формой выходного сигнала. Кроме того заложить какие–либо эффекты для усиления богатства и разнообразия издаваемых звуков. Такие чипы часто называются Programmable Sound Generators (PSG) — программируемые генераторы звука.

Например в ZX Spectrum 128 стоял чип AY–3–8910 от General Instrument в котором было три независимых генератора прямоугольного сигнала (A,B и C) у каждого можно было задать отдельно громкость и частоту.
Прямоугольный сигнал на графике выглядит так:

Изображение

что по сути сильно напоминает вышеописанный однобитовый "вкл/выкл" по таймеру звука спикера у IBM PC и это неслучайно — частота сигналов так же задаётся как верхнее значение для таймера, отсчитывающего время до переключения сигнала.
Кроме того был один генератор белого шума, который мог быть подмешан в любой из каналов A,B и/или C и мог немного менять своё звучание.
А в качестве "обогатителя" звука в чипе присутствовал генератор так называемой "огибающей". "Огибающая" могла быть сигналом с одной из следующих форм с контролируемой частотой:

Изображение

Огибающая могла быть применена к любому из каналов (в т.ч. к нескольким сразу) и в этом случае громкость сигнала в нём контролировалась напрямую величиной значения огибающей в данный момент времени — громкость звука могла "плавать" во времени, обогащая его тембры.
Вот видео с множеством мелодий на чипе AY–3–8910:

Техника программирования мелодий на подобных чипах состояла в том, что процессор с некой периодичностью (в консолях чаще всего во время VBlank, полный аналог чего был и в ZX Spectrum) менял параметры генераторов, большую же часть времени занимаясь своей работой.

На Famicom/NES/Денди был кастомный чип с двумя генераторами прямоугольного, одним треугольного, одним шумовым и одним низкокачественным цифровым генератором (крохотный буфер PCM–звука низкой битности, зачастую используется как зацикленный фрагмент). Кроме того звук каналов можно было обогащать приёмом отдалённо похожим на "огибающую" — через периоды "повтора–затухания", я тут подробно описывать не буду. Многие игроки в эту консоль сталкивались с таким явлением, что если вытащить картридж во время игры, то мелодия часто "застывала" навечно звучащей на паре чистых нот — это как раз следствие того, что генератор звука не получая обновлений от ЦП по VBlank продолжал генерировать ноты заданные последней установкой параметров.

На Commodore 64 стоял чип от MOS Technology — SID 6581. У него было три генератора сигнала в каждом из которых можно было независимо выбрать форму сигнала — пилообразную, треугольную, прямоугольную или белый шум, многорежимный фильтр и независимый контроль ADSR–огибающих для каждого канала. Про "ADSR" я расскажу чуть ниже.

Все подобные микросхемы были устроены сравнительно несложно и генерировали довольно примитивный, "искусственно звучащий" звук. Сейчас такое звучание и сами такие мелодии называют chiptune и люди увлекающиеся до сих пор создают для них мелодии.

Однако не только производители компьютерной техники бились за звук. На электронную музыку в том числе цифровую обратили внимание так же профессиональные музыканты и производители музыкальных инструментов...

#266
13:46, 19 апр. 2018

"В 1887 году к Торакусу Ямахе, занимавшемуся тогда ремонтом медицинских инструментов в японском городе Хамамацу, обратилась местная школа с просьбой починить язычковый орган (фисгармонию) американского производства. После завершения ремонта, Ямаха увлёкся конструированием музыкальных инструментов и в 1889 году основал Yamaha Organ Manufacturing Company, а чуть позже — Nippon Gakki. Сегодня эта компания известна как Yamaha Corporation и уже долгие годы является крупнейшим производителем музыкальных инструментов."

Музыканты, в отличие от компьютерщиков, хотели большего, чем "пищалки" и "шкворчалки" чиптюна. Одна из задач была: добиться от электроники звучания максимально похожего на настоящие традиционные музыкальные инструменты.
И главной "рабочей лошадкой" тут стал синусоидальный сигнал:

Изображение

Синусоидальные или "гармонические" колебания — частый гость в физических процессах. Так, колебание струны математически описывается наложением синусоид. Чистая синусоида звучит при этом "слишком чисто". В общем музыканты накинулись на задачу и тоже начали изобретать как бы подешевле, но наиболее широко охватить целые классы звучаний и параметризовать их.
На некотором этапе мейнстримом в этом деле стал так называемый FM–синтез. Аббревиатура "FM" как и в радио происходит от словосочетания "Frequency Modulation (Частотная Модуляция)". Идея заключается в том, что мы сперва берем настраиваемые генераторы синусоид, называем их "операторами", а потом даём возможность задавать текущую частоту одного оператора значением текущей амплитуды (величины) другого оператора — это и называется "использовать FM–модуляцию". И вот что получалось — синусоида могла плавно менять свою частоту со временем:

Изображение

В результате мы могли запрограммировать, чтобы нота, например, из высокой плавно становилась низкой или же быстро "вибрировала" в тональности, а не звучала чисто. Дальше — хуже, амплитуду модулированного оператора можно было вновь использовать как модулятор для другого! Варианты звучания резко множились, так что сидеть и перебирать их можно было днями напролёт.

Кроме модуляции сигнала музыканты так же широко использовали динамическую регулировку громкости инструмента — ту самую "огибающую". Популярность получил вариант "ADSR–огибающей", когда громкость сигнала регулировалась в рамках четырёх настраиваемых периодов: Attack — нарастание громкости, Decay — спад громкости, Sustain — задержка громкости на постоянном уровне и, наконец, Release — окончательное затухание сигнала.
График такой огибающей выглядит примерно так:

Изображение

Такая огибающая позволяет неплохо имитировать то как затухает звук от настоящих музыкальных инструментов — фортепьяно, гитары и т.д. Кроме всего вышеописанного на звук в музыкальных синтезаторах накладывались и разные прочие эффекты — эхо и т.п.

В 1987 году канадская фирма Adlib взяла у производителя музыкальных синтезаторов Yamaha чип FM–синтеза YM3812 и интегрировала его в IBM PC воткнув в ISA–слот в виде музыкальной карты.
Программно чип управлялся через порт ввода–вывода $388, он для компьютера выглядел как массив из 244 регистров, которые описывают параметры 9 независимых каналов, каждый из которых состоит из двух осцилляторов которые можно комбинировать в FM–синтез.
Немного позже, после того как звуковая карта от Adlib получила популярность, сингапурская фирма Creative Technology взяла тот же самый музыкальный FM–чип от Yamaha, добавила к нему чип для воспроизведения цифрового PCM–звука и выпустила в виде звуковой карты под брендом Sound Blaster. В Sound Blaster музыкальный чип был так же замаплен на порт ввод–вывода $388, что делало его полностью совместимым со звуковой картой Adlib. Кроме того порты управления PCM–чипом и зеркало портов для управления FM–чипом были вынесены по умолчанию в группу портов начинающихся с $220, что наверняка помнят все из тех здесь кто запускал в DOS setup.exe в самых разных играх.

Я лично ранее думал, что все эти звуковые карты сразу "дружили" общим форматом музыкальных файлов и протоколом управления синтезаторами — "MIDI", но в реальности создателям игр под DOS приходилось создавать свои форматы файлов и звуковые драйвера, которые так же как и в консолях и 8–битных компьютерах периодически меняли параметры инструментов подобранных музыкантами вручную.
Но правда тут музыкантам могло помочь то, что существовало большое количество настоящих музыкальных синтезаторов от Yamaha Corporation с тем же самым чипом.
На следующем видео 8bit–guy использует этот факт для извлечения точно такого же звука, как в компьютерной игре, из синтезатора Yamaha PSS–470, а сразу после этого демонстрирует, что если пытаться на синтезаторе нажать более 9 клавиш одновременно — последующие не звучат (если само не перемотает — перемотать на 2:35):

А вот такая консоль как Sega Mega Drive имеет сразу два чипа из вышеописанных классов:
— SSG–чип Texas Instruments SN76489 (для совместимости с 8–битной Sega Master System)
— FM–чип Yamaha YM2612 (шестиканальный FM–синтез с четырьмя операторами на канал)

Со временем синтез музыки специализированными чипами уступил место программной генерацией звука самим центральным процессором (куда так же можно отнести и распаковку звука из MP3 или OGG, ведь происходит это при непосредственном участии ЦП). Ведь уже в 1998 году в игре Unreal 1 музыка генерировалась процессором из самплов комбинируемых программным синтезатором — так называемая "трекерная музыка", а еще через пару лет запущенный WinAMP не влиял на работоспособность MS Word. И современные синтезаторы уже тоже внутри содержат цифровой банк оцифрованных звуков настоящих инструментов, комбинируемых программно встроенным процессором.
Эпоха специализированных чипов синтеза, пожалуй, давно уже канула в лету.

#267
(Правка: 7:33) 7:32, 24 мая 2018

Решил подбить с вики размеры тех-процесса (нанометры) по годам и поколениям процессоров в одну таблицу: (начиная с https://en.wikipedia.org/wiki/10_%C2%B5m_process )

+-------+------+--------------------------------------+
|  нм.  | год  | некоторые представители              |
+-------+------+--------------------------------------+
| 10000 | 1971 | i4004, i8008                         |
|  6000 | 1974 | i8080, Z80                           |
|  3000 | 1977 | i8086, m68k, ARM                     |
|  1500 | 1982 | i286                                 |
|  1000 | 1985 | i386                                 |
|   800 | 1989 | i486, Pentium                        |
|   600 | 1994 | Pentium, PowerPC 601                 |
|   350 | 1995 | Pentium II, AMD K5/6                 |
|   250 | 1997 | Pentium III Katmai, AMD K6-III       |
|   180 | 1999 | Pentium III Coppermine               |
|   130 | 2001 | Pentium 4, Intel Xeon, AMD Athlon XP |
|    90 | 2004 | Pentium 4 Prescott, AMD Athlon 64    |
|    65 | 2006 | Intel Core, AMD Phenom, IBM Cell     |
|    45 | 2008 | Intel Core, IBM Power7               |
|    32 | 2012 | Intel Core, AMD FX/Bulldozer         |
|    14 | 2014 | Core (Ivy Bridge)                    |
|    10 | 2017 | Intel Core M, AMD Ryzen              |
+-------+------+--------------------------------------+

Сведения по представителям обрывочные и не особо неточные, особенно во второй половине, когда мешанина всего одновременно присутствовала на рынке и выходила на разных тех-процессах. Старался вычленить первых представителей.

#268
10:42, 24 мая 2018

=A=L=X=
> Рассматривая исходники stdio Hisoft C на 8-битном ZX Spectrum.

ооооооооо мой первый C - это как первый секс, такое бывает раз в жизни :):):)

#269
(Правка: 14:17) 14:16, 24 мая 2018

Блин. Когда то на Спектруме 128 к 
На заставке перед игрой Dragon Ninja  был классный ремейк музона Игоря Корнелюка "Возвращайся".
Звучало намного лучше оригинала.

Жаль что не могу найти.

Страницы: 117 18 19 2045 Следующая »
ФлеймФорумЖелезо