Воспоминания, Turbo C 01.06.2024
Всем привет! Сегодня уже наступило лето. Я хотел бы вспомнить про Turbo C. В конце 80х на компе был установлен толи Turbo C 1.0, толи 2.0, уже точно не помню. Среда была достаточно примитивна, но если умеешь программировать на Си, то можно было кучу денег заработать. Вот так выглядела лицензионная коробка:
Но после Turbo C, у нас появился дома сначало Borland C++ 3.0, а потом и Borland C++ 4.5 см. https://groups.germany.ru/1299414/f/40785707.html?Cat=&pag.... Turbo C 1.0 и 2.0 мог компилировать только под MS-DOS и в 16 бит. Только Borland C++ 2.0 научился компилировать под Windows, но ещё поддерживал только 16 бит. А вот Borland C++ 4.5 мог компилировать и под Win32s.
Вот так выглядела среда разработки:
Чтобы скопировать блоки в коде, нужно было нажать CTRL+K и B, и перейти на нужное место и нажать на CTRL+K и K. А чтобы вставить код в нужное место, нужно было перейти на нужно место, и нужно было нажать CTRL+K и C. Там была библиотека работы со строками, с памятью, с файлами, с BIOS-ом, графическая библиотека BGI, библиотека работы с консолью. Возможно (но я точно не уверен, т.к. уже толком не помню) там был встроен ассемблер. Так-же там можно было создавать свою библиотеку. А так-же там был отладчик. У тех у кого была голова, те могли разбогатеть. Turbo C можно сказать это как лего, который даёт кирпичики, окна, двери, и потолки, а из них строишь любой дом. Так-же были стороннии библиотеки, спомощью которых упрощалась жизнь программиста на Turbo C.
Так-же забыл перечислить в Turbo C, были библиотеки, спомощью которых можно было управлять вводом с клавиатуры, работа с аппаратным прерыванием. Но если не умел хорошо программировать на Си, в то время можно было испортить даже компьютер. Современная операционная система начиная от Windows NT 3.x и Windows 95, а так-же IBM OS/2 Warp если увидит ошибку в программе просто забьёт процесс. Компилятор Turbo C 1.0 и 2.0, а так-же программы написаны на нём, нельзя запустить на современном компьютере если там стоит современный Windows. Чтобы запустить среду Turbo C 1.0 и 2.0 или написанные на них программы, нужно установить либо FreeDOS или эмулятор DOS. Так-же можно перекомпилировать на современном компиляторе, который совместим с Си.
Вот пару примеров написанные на Turbo C:
Работа с памятью и строками:
#include <stdio.h> #include <alloc.h> int main(void) { char *buf; buf = (char *)malloc(512); /* Резервируем память на 512 байт */ strcpy(buf, "HELLO"); /* Копируем в переменную buf, слово HELLO */ strcat(buf, " FROM uscheswoi_82"); /* Добавляем в переменную buf, слово FROM uscheswoi_82 */ printf("\n%s", buf); /* Выводим содержимое buf на экран */ free(buf); /* Освобождаем зарезервированную память */ }
Работа с консолью:
#include <conio.h> int main(void) { textattr(BLUE*0x10+WHITE); /* Устанавливаем синий фон, и белые буквы */ clrscr(); /* Очищаем экран дисплея, фон становится синим, а буквы белыми */ gotoxy(1, 1); /* Перемещаем курсор на 1 строку, 1 колонку */ cprintf("HELLO uscheswoi_82"); /* Отображаем HELLO uscheswoi_82 */ }
Работа с файлами:
#include <stdio.h> int main(void) { FILE *f; char buf[4096]; int sz = 0; f = fopen("test.txt", "w"); /* Открываем файл test.txt для записи */ fprintf(f, "%s d", "HELLO uscheswoi_82", 3); /* Пишим в файл HELLO uscheswoi_82 03 */ fclose(f); /* Закрываем файл */ f = fopen("test.txt", "r"); /* Открываем файл для чтения */ /* Если файл существует */ if(f != NULL) { fseek(f, 0L, SEEK_END); /* Перематываем в конец файла */ sz = ftell(f); /* Получаем текущую позицию, это нужно чтобы знать сколько байт записать в переменную buf */ fseek(f, 0L, SEEK_SET); /* Перематываем в начало файла */ fread(buf, sz-1, 1, f); /* Считываем текст из файла, т.е. "HELLO uscheswoi_82 03" */ printf("\n%s", buf); /* Печатаем на экране "HELLO uscheswoi_82 03" */ } fclose(f); /* Закрываем файл */ }
Благодаря, Turbo C 1.0 / 2.0, Borland C++ 3.0 и 4.5 мы могли себе всё позволить. Некоторые вещи программировать муторно, но всё же, лучше программировать на Си, чем работать токарем, подметать улицы, работать строителем. Если голова есть, то можно работать дома, а это значит спишь когда хочешь, встаёшь когда хочешь. В начале 90х ездить в автобусе на работу это был ад. От дома до работы каждый день 1 час езды, и назад 1 час езды. В начале 90х можно было программу отсылать из дома, спомощью программы Symantec Norton pcAnyWhere и спомощью диал-ап модема 56k см.
Благодаря Turbo C я изучил язык Си, и попал в немецкий колледж. Т.к. когда я прежде чем поступить в колледж я писал письмо директору, что я хочу поступить в колледж, и я знаю такие-то языки программирования.
Благодаря Си, я смог освоить легко Си++, Java, C#, JavaScript, и PHP. Благодаря знания Си и умение работы со средой Turbo C, мне легко дался в освоение Turbo/Borland Pascal. В Turbo/Borland Pascal некоторые функции один к одному взяты из Си.
В спешки забыл написать return, во всех трёх примерах нужно обязательно написать так:
int main(void) { ... return 0; }
Итак продолжим наше воспоминание. Вот пример программы, точнее алгоритма, которая/который рисует меню в MS-DOS:
#include <stdio.h> #include <conio.h> #include <bios.h> #define LEFT 19200 #define RIGHT 19712 #define ESC 283 #define ENTER 7181 #define MAX_MENUS 4 char *menus[MAX_MENUS] = {"File", "Edit", "Options", "Help"}; int menus_pos[MAX_MENUS] = {1, 10, 20, 30}; int main(void) { int key = 0, sel = 0, j = 0; textattr(BLACK*0x10+LIGHTGRAY); clrscr(); while(!kbhit()) { gotoxy(1, 1); textattr(LIGHTGRAY*0x10+BLACK); window(1, 1, 1, 80); for(j=0; j<80; j++) cprintf(" "); gotoxy(1, 1); for(j=0; j<MAX_MENUS; j++) { gotoxy(menus_pos[j], 1); cprintf(" %s ", menus[j]); } gotoxy(menus_pos[sel], 1); textattr(GREEN*0x10+YELLOW); cprintf(" %s ", menus[sel]); key = bioskey(0); switch(key) { case ENTER: gotoxy(1, 2); textattr(RED*0x10+YELLOW); cprintf("Selected menu: %s", menus[sel]); break; case ESC: return 0; break; case LEFT: if(sel > 0) sel--; break; case RIGHT: if(sel < MAX_MENUS-1) sel++; break; } } return 0; }
Результат работы программы/алгоритма, который я написал на Си:
Продолжим разговор про программирования на Си. Но прежде чем начнём, пару слов об одном форумчане на Казахстанском форуме. Хоть мы были по разную сторону когда я сидел в Казахстанском форуме, т.е. он за Россию, а я за Украину, но вообще он в политику невмешивался, но меня не любил из-за того что я не за Россию, а за Украину, и из-за того что выяснял отношения с другими пользователями. Ну так вот, он несколько дней назад сгорел в Алматы, и ещё погиб его брат. У него не было женщин и детей, был инвалидом как я из-за инсульта, и сидел в форуме ночью, потому-что после инсульта проблемы были якобы со сном. Он многое сделал для Казахстанского форума, был очень добрым, без него бы Казахстанский форум бы загнулся, и администратор Казахстанского форума должен поставить ему золотой памятник за большую заслугу. Вместо заслуги, у него стоит теперь статус в профиле RIP. А так тот форум в Казахстане потихоньку вымерает, т.к. за любую ерунду там можно получить вечный бан, после закрытия vse.kz, многие перебрались в другие русскоязычные форумы, а некоторые сюда. Короче пусть земля будет пухом и покойся с миром.
Ладно давайте дальше программировать. Короче я час назад сделал программу, для отображения помощи или подсказки. Позже я постараюсь закончить.
#include <stdio.h> #include <conio.h> #define LINK_BEGIN 0x01 /* Начало ссылки */ #define LINK_END 0x02 /* Конец ссылки */ #define SET_BKCOLOR 0x03 /* Установить цвет фона и цвет текста */ #define GOTOXY 0x04 /* Перейти на X,Y координату */ #define BEGIN_OF_TOPIC 0x10 /* Начало помощи */ #define END_OF_TOPIC 0x11 /* Конец помощи */ typedef struct { unsigned char x; unsigned char y; unsigned char current_page; int sz; unsigned char jump_to; } LINK_POS; int main(void) { FILE *f; LINK_POS links[4096]; int link_count = 0; int status = 0; unsigned char ch; unsigned char current_topic = 0; unsigned char fg, bg; unsigned char x, y; textattr(BLACK * 0x10 + LIGHTGRAY); clrscr(); f = fopen("test.hlp", "r+b"); if(f != NULL) { while(1) { if(feof(f)) break; ch = fgetc(f); if(ch == BEGIN_OF_TOPIC) { current_topic = fgetc(f); printf("Current topic:%d ", current_topic); while(1) { if(feof(f)) break; ch = fgetc(f); if(ch == END_OF_TOPIC) { fclose(f); return 0; } else if(ch == GOTOXY) { x = fgetc(f); y = fgetc(f); gotoxy(x, y); } else if(ch == SET_BKCOLOR) { fg = fgetc(f); bg = fgetc(f); textattr(bg * 0x10 + fg); } else if(ch == LINK_BEGIN) { links[link_count].x = wherex(); links[link_count].y = wherey(); links[link_count].sz = 0; links[link_count].current_page = current_topic; ch = fgetc(f); links[link_count].jump_to = ch; while(1) { if(feof(f)) break; ch = fgetc(f); if(ch == LINK_END) break; else cprintf("%c", ch); } } else if(ch == LINK_END) links[link_count].sz = wherey(); else cprintf("%c", ch); } } } } fclose(f); return 0; }
Справка, ну или подсказка будет примерно такой:
Вот код, который генерирует справку в моём придуманном формате HLP, это бинарый файл:
#include <stdio.h> #define LINK_BEGIN 0x01 #define LINK_END 0x02 #define SET_BKCOLOR 0x03 #define GOTOXY 0x04 #define BEGIN_OF_TOPIC 0x10 #define END_OF_TOPIC 0x11 void begin_of_topic(FILE *f, char unsigned page_id) { fputc(BEGIN_OF_TOPIC, f); fputc(page_id, f); } void write_data(FILE *f, char *buf) { fprintf(f, "%s", buf); } void new_line(FILE *f) { fputc('\n', f); } void end_of_topic(FILE *f) { fputc(END_OF_TOPIC, f); } void goto_xy(FILE *f, char unsigned x, char unsigned y) { fputc(GOTOXY, f); fputc(x, f); fputc(y, f); } void set_bkcolor(FILE *f, char unsigned bg, char unsigned fg) { fputc(SET_BKCOLOR, f); fputc(bg, f); fputc(fg, f); } void link(FILE *f, char unsigned page_id, char *text) { fputc(LINK_BEGIN, f); fputc(page_id, f); fprintf(f, "%s", text); fputc(LINK_END, f); } int main(void) { FILE *f; f = fopen("test.hlp", "w+b"); begin_of_topic(f, 1); write_data(f, "Hello World 1!"); new_line(f); new_line(f); link(f, 2, "Goto 2"); end_of_topic(f); begin_of_topic(f, 2); write_data(f, "Hello World 2!"); new_line(f); new_line(f); link(f, 1, "Goto 1"); end_of_topic(f); fclose(f); return 0; }
Я забыл выше код:
... else if(ch == LINK_END) links[link_count].sz = wherey(); ...
Нужно добавить имхо вот это:
... else if(ch == LINK_END) { links[link_count].sz = wherey(); link_count ++; } ...
Все программы я программирую на моём лицензионном Borland C++ 2.0 см. https://groups.germany.ru/1299414/f/40785707.html?Cat=&pag...
Все программы я программирую на моём лицензионном Borland C++ 2.0
Имел ввиду в этой ветке/теме.
Всем добрый вечер!
Программу для отображение справки я продолжу позже, а сейчас сделаю две небольшие программы. Одна программа генерирует и рисует ASCII таблицу, а другая рисует окно в MS-DOS.
Вот программа, которая генерирует ASCII таблицу ascii.c:
#include <stdio.h> #include <conio.h> int main(void) { unsigned int a; int y=1, x=1; clrscr(); for(a=0; a<256; a++) { gotoxy(x, y); if(a == 0) { textattr(BLACK*0x10+RED); cprintf("X N |", a); } else if(a == 7) { textattr(BLACK*0x10+RED); cprintf("X N |", a); } else if(a == 8) { textattr(BLACK*0x10+RED); cprintf("X N |", a); } else if(a == '\n') { textattr(BLACK*0x10+RED); cprintf("X N |", a); } else if(a == ' ') { textattr(BLACK*0x10+RED); cprintf("X S |", a); } else if(a == '\r') { textattr(BLACK*0x10+RED); cprintf("X N |", a); } else if(a == '\g') { textattr(BLACK*0x10+RED); cprintf("X B |", a); } else { textattr(BLACK*0x10+LIGHTGRAY); cprintf("X %c |", a, a); } y++; if(y >= 25) { y = 1; x += 7;} } return 0; }
Вот результат работы программы:
Вот алгоритм рисования окна на Си window.c:
#include <stdio.h> #include <conio.h> #define LINE_VERT 0xBA #define LINE_HORIZ 0xCD #define TOP_RIGHT 0xBB #define BOTTOM_RIGHT 0xBC #define BOTTOM_LEFT 0xC8 #define TOP_LEFT 0xC9 void draw_window(int l, int t, int r, int b) { int j; window(l, t, r+1, b+1); textattr(BLUE*0x10+WHITE); clrscr(); gotoxy(l, t); cprintf("%c", TOP_LEFT); gotoxy(r, t); cprintf("%c", TOP_RIGHT); gotoxy(l, b); cprintf("%c", BOTTOM_LEFT); gotoxy(r, b); cprintf("%c", BOTTOM_RIGHT); for(j=2; j<r; j++) { gotoxy(j, 1); cprintf("%c", LINE_HORIZ); gotoxy(j, b); cprintf("%c", LINE_HORIZ); } for(j=2; j<b; j++) { gotoxy(l, j); cprintf("%c", LINE_VERT); gotoxy(r, j); cprintf("%c", LINE_VERT); } gotoxy(2, 2); } int main(void) { textattr(BLACK*0x10+LIGHTGRAY); clrscr(); draw_window(1, 1, 15, 15); cprintf("HELLO WORLD"); return 0; }
Нам понадобяться такие ASCII символы:
Вуаля! А вот и результат, наше окошко:
Примерно вот так программисты программировали в начале 90х, и зарабатывали неплохие денюжки!
Всё пошёл спатенькать, завтра возможно начну новую но очень интересную тему. Всё спок ночи всем!
Улучшил только-что код меню, незаметил while(!kbhit()), а надо while(1):
#include <stdio.h> #include <conio.h> #include <bios.h> #define LEFT 19200 #define RIGHT 19712 #define ESC 283 #define ENTER 7181 #define MAX_MENUS 4 char *menus[MAX_MENUS] = {"File", "Edit", "Options", "Help"}; char *menus_help[MAX_MENUS] = {"Create a new file, open an exist file, or save into a file", "Copy, paste, cut, etc.", "Options of program", "Help"}; int menus_pos[MAX_MENUS] = {1, 10, 20, 30}; int main(void) { int key = 0, sel = 0, j = 0; textattr(BLACK*0x10+LIGHTGRAY); clrscr(); while(1) { gotoxy(1, 1); textattr(LIGHTGRAY*0x10+BLACK); for(j=0; j<80; j++) cprintf(" "); gotoxy(1, 24); textattr(LIGHTGRAY*0x10+BLACK); for(j=0; j<80; j++) cprintf(" "); gotoxy(1, 1); for(j=0; j<MAX_MENUS; j++) { gotoxy(menus_pos[j], 1); cprintf(" %s ", menus[j]); } gotoxy(menus_pos[sel], 1); textattr(GREEN*0x10+YELLOW); cprintf(" %s ", menus[sel]); gotoxy(1, 24); textattr(LIGHTGRAY*0x10+BLACK); cprintf(" %s ", menus_help[sel]); gotoxy(1, 1); key = bioskey(0); switch(key) { case ENTER: gotoxy(1, 2); textattr(RED*0x10+YELLOW); cprintf("Selected menu: %s ", menus[sel]); break; case ESC: textattr(BLACK*0x10+LIGHTGRAY); clrscr(); return 0; break; case LEFT: if(sel > 0) sel--; else sel = MAX_MENUS-1; break; case RIGHT: if(sel < MAX_MENUS-1) sel++; else sel = 0; break; } } return 0; }
А вот и результат! Вуаля!:
См. https://i.ibb.co/0tBhjGw/bandicam-2024-06-06-14-35-57-065....
Всем добрый вечер!
Сегодня не хочу заниматься Embedded, а хочу продолжить разговор про программирование на Си. Давайте сегодня поговорим про библиотеку Turbo C BGI. Это очень классная библиотека, для работы с графикой. Там можно рисовать точки, окружности, прямоугольники, изгибы, 3х-мерные прямоугольники, выводить текст, менять фон и цвет, делать заливку. Я сделаю пример светофора на Си, вот код traficlight.c:
#include <stdio.h> #include <graphics.h> #define TRAFICLIGHT_BORDER_COLOR LIGHTGRAY #define TRAFICLIGHT_BG_COLOR DARKGRAY #define TRAFICLIGHT_BG_COLOR_RED RED #define TRAFICLIGHT_BG_COLOR_YELLOW BROWN #define TRAFICLIGHT_BG_COLOR_GREEN GREEN #define TRAFICLIGHT_ON_BG_COLOR_RED LIGHTRED #define TRAFICLIGHT_ON_BG_COLOR_YELLOW YELLOW #define TRAFICLIGHT_ON_BG_COLOR_GREEN LIGHTGREEN int main(void) { int color = 0; int gdriver = DETECT, gmode, errorcode; initgraph(&gdriver, &gmode, ""); errorcode = graphresult(); if(errorcode != grOk) return -1; setbkcolor(BLUE); setcolor(WHITE); outtextxy(10, 450, "Press any key to quit..."); setcolor(TRAFICLIGHT_BORDER_COLOR); rectangle(10, 10, 70, 200); rectangle(30, 200, 50, 290); setfillstyle(SOLID_FILL, TRAFICLIGHT_BG_COLOR); floodfill(12, 12, TRAFICLIGHT_BORDER_COLOR); setfillstyle(SOLID_FILL, TRAFICLIGHT_BG_COLOR); floodfill(32, 202, TRAFICLIGHT_BORDER_COLOR); circle(40, 42, 25); circle(40, 102, 25); circle(40, 162, 25); while(!kbhit()) { setfillstyle(SOLID_FILL, TRAFICLIGHT_BG_COLOR_RED); floodfill(42, 44, TRAFICLIGHT_BORDER_COLOR); setfillstyle(SOLID_FILL, TRAFICLIGHT_BG_COLOR_YELLOW); floodfill(42, 104, TRAFICLIGHT_BORDER_COLOR); setfillstyle(SOLID_FILL, TRAFICLIGHT_BG_COLOR_GREEN); floodfill(42, 164, TRAFICLIGHT_BORDER_COLOR); if(color == 0) { setfillstyle(SOLID_FILL, TRAFICLIGHT_ON_BG_COLOR_RED); floodfill(42, 44, TRAFICLIGHT_BORDER_COLOR); } else if(color == 1) { setfillstyle(SOLID_FILL, TRAFICLIGHT_ON_BG_COLOR_RED); floodfill(42, 44, TRAFICLIGHT_BORDER_COLOR); setfillstyle(SOLID_FILL, TRAFICLIGHT_ON_BG_COLOR_YELLOW); floodfill(42, 104, TRAFICLIGHT_BORDER_COLOR); } else if(color == 2) { setfillstyle(SOLID_FILL, TRAFICLIGHT_ON_BG_COLOR_GREEN); floodfill(42, 164, TRAFICLIGHT_BORDER_COLOR); } else color = -1; delay(1000); color++; } getch(); closegraph(); return 0; }
Вот результаты работы программы светофор, написаный на языке Си:
Всем добрый вечер! Закрыл группы, потому-что была странная активность, мои посты начали смотреть по 100-200 е в день . Сейчас опять открыл. Короче продолжим болтавню программирования на Си. Сделаем симулятор планет, но потом код подправлю. Вот код:
#include <graphics.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #define PI 3.14159265359 #define PLANETS_COUNT 9 void draw_planet(int cx, int cy, int x, int y, float angle, int fg, int bg); int main(void) { float x[PLANETS_COUNT], y[PLANETS_COUNT], angle[PLANETS_COUNT], step[PLANETS_COUNT]; int planets; char buf[80]; int gdriver = DETECT, gmode, errorcode; initgraph(&gdriver, &gmode, ""); errorcode = graphresult(); if(errorcode != grOk) return -1; for(planets=0; planets<PLANETS_COUNT; planets++) { if(planets > 0) { x[planets] = x[planets-1]+15; y[planets]=y[planets-1]+15; } else { x[planets] = 40; y[planets]=40; } } for(planets=0; planets<PLANETS_COUNT; planets++) { angle[planets] = rand() % 50; step[planets] = 1 + rand() %4; } while(!kbhit()) { setcolor(WHITE); circle(250, 250, 20); setfillstyle(SOLID_FILL, YELLOW); floodfill(252, 252, WHITE); for(planets=0; planets<PLANETS_COUNT; planets++) { angle[planets] += step[planets]; if(angle[planets] >= 359) angle[planets] = 0; draw_planet(250, 250, x[planets], y[planets], angle[planets], WHITE, BLUE); sprintf(buf, "%d %f", planets, angle[planets]); outtextxy(10, 20+(planets*10),buf); } cleardevice(); } getch(); closegraph(); return 0; } void draw_planet(int cx, int cy, int x, int y, float angle, int fg, int bg) { float nx, ny; nx = (x * cos(angle*(PI/180))) - (y * sin(angle*(PI/180))); ny = (x * cos(angle*(PI/180))) + (y * sin(angle*(PI/180))); setcolor(fg); circle(cx + nx, cy + ny, 5); setfillstyle(SOLID_FILL, bg); floodfill(cx+2+nx, cy+2+ny, fg); }
Улучшу код, а так-же покажу программу в дейтсвие чуть позже.