Я всегда любил читать. Начиная с детского сада. Потом в школе я перечитал почти всю библиотеку. Когда пошел на работу, в лихие девяностые, покупал на рынках кучу всяких книг. Время было тяжелое. Многие уезжали в Германию на ПМЖ. Уехал и мой друг. Потом через несколько лет в конце девяностых прислал посылку в которой кроме невиданных заморских сладостей лежало 3 компьютера Sharp PC3000.

Именно таких:



В итоге из них 2 запустились, а третий был оставлен на запчасти. По сути дела это был обычный IBM PC XT на процессоре 8088 с 1 мб памяти, графическим дисплеем с 4 градациями яркости, портами COM, LPT, Dock, двумя слотами под PCMCIA в одном из которых я нашел карту памяти на 512 кб на батарейке CR2032.



Радости моей не было предела!

Но посидев, и покрутив в руках эту вещицу, было непонятно для чего ее можно использовать. В этом палмтопе были предустановлены приложения в основном для бизнеса — календарь, записная книжка, файловый менеджер. Разъемы Com и LPT были проприетарными. Миниатюрные, похожие на своих полноценных собратьев, но без штырьков, а ножевые, подобные PCI или PCIe. Интернет в то время выдавали по талонам был в настолько зачаточном состоянии, что подключиться можно было только ночью и не на долго, потому что связь постоянно рвалась. В итоге была найдена распиновка разъемов, вытравлены ножевые переходники и изготовлен нуль-модемный кабель для связи с большим братом. Но в итоге встроенной утилитой соединится было нельзя. Приложение LapLink, которое я нашел в интернете и не мог никак вытащить из палмтопа было не той версии. Поиски продолжались и в итоге я нашел дистрибутив с утилитами.

Казалось бы, проблема решена, закачивай программы и пользуйся в свое удовольствие. Помучался я неделю. Перебрал всевозможные программы, в основном игрушки. Но в силу отступления от классического формата IBM PC, многие приложения либо не работали, либо работали некорректно. Либо им не хватало памяти на карте. Поэтому я его забросил до лучших времен.

Через некоторое время я устроился на работу на спиртзавод дежурным слесарем КИПиА. В дневную смену работы хватало, а вот в ночную заняться было нечем, так как оборудование было новым и практически не ломалось. Книги я уже не покупал, так как на толкучках продавались диски с кучей всякой литературы в DOS txt формате. И, купив один такой диск, можно было читать его несколько лет. Тут ко мне и пришла идея использовать свой Микро PC.

Вся особенность реализации памяти состояла в том, что встроенные приложения запускались с ROM диска и они были адаптированы под его использование. Запуск системы и конфиги лежали на встроенном RAM диске емкостью 76 кб, энергонезависимость которого поддерживалась батарейкой. Был еще и RAM диск 1мб, энергонезависимость которого поддерживалась основной батареей. В итоге я принял решение написать сверхмалое приложение. И вроде бы начал на ассемблере, но отсутствие средств отладки убивало. Ну помните наверное tasm… В итоге запустил на ББ Turbo C 2.0 и начал ваять. Первая же загрузка в Sharp показала что ничего не работает. Если на ББ все работало идеально, на палмтопе приложение ничего на экран не выдавало. Пришлось пойти на крайние меры и урезав до минимума Turbo C засунуть его в палмтоп. В итоге я все-таки написал читалку и несколько лет наслаждался чтением любимых книг в рабочее время. Причем экран в Sharp PC3000 оказался самым удобным для чтения, потому-что был сделан по старой классической технологии без подсветки. Режим 80х25 был самым оптимальным и буквы на экране были такие же по размеру как и в книгах. Палмтоп работал от трех батареек типа АА. Но наличие схемы позволило мне установить аккумы и подключить через стабилизатор схему слаботочного заряда. Батарейки и аккумуляторы ел он хорошо, поэтому аккумуляторы использовались только для сохранения информации в RAM диске. Да и нормальных аккумуляторов в то время сложно было найти, поэтому эксплуатировалась читалка всегда подключенной к сети. Ну или на короткое время от аккумуляторов для переноса в другое место.

Исходник программы
#include <dir.h>
#include <bios.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <stat.h>
#include <alloc.h>
#include <conio.h>
#include <stdio.h>
#include <stat.h>
#include <stdlib.h>
#include <stdarg.h>
#include <graphics.h>
#include <process.h>

unsigned char qui,c,membl[2000],fname[20],memtxt[128],Statusin,me;
unsigned int h,pos=0,ads,seg,t,t1,t2,memseg,memoffset,membuff,tx,rx,startbuff,buffoff=0,buffbeg,xcor,ycor,buttons,tb;
int *memblock,xpos,ypos;
long membu,memtext,lenght;
unsigned long textposit;
int memcoord,fontadr;
int    GraphDriver,txtfile;
int    GraphMode;
double AspectRatio;
int    MaxX, MaxY;
int    MaxColors;
int    ErrorCode;
struct palettetype palette;

/*struct ffblk ffblk;*/
unsigned char filelist[192][15];
unsigned char i,x,xp,yp,xl,p,zc;
char *driv,*diskname;
unsigned int key,drive;
int z,filepos,dr,pgs;



void main()
{
      void loadfont();
      void gettextadr();
      void Help();
      void Search();
      void zprintf();
      void Initialize();
      void book();
      void Oscill();
      void Quit();
      void cls();
	void prtmen();
	void files();
	void drivesel();



	 char *buf;
	 clrscr();
	 drive=getdisk();
	 if (drive==0) diskname="A";
	 if (drive==1) diskname="B";
	 if (drive==2) diskname="C";
	 if (drive==3) diskname="D";
	 if (drive==4) diskname="E";
	 files();
	 loadfont();
         printf("National font loaded\n\n");
	 filepos=0;
	 clrscr();
	 while (qui!='q') {
		 while (key!=0x1c0d) {
			prtmen();
			gotoxy(1,25);
			sprintf(buf,"%-3s    ", filelist[drive]);
			driv=buf;
			 while (bioskey(1)==0) ;
				key=bioskey(0);
				if (key==0x5000) { /* down*/
					filepos=filepos+1;
					}
				if (key==0x4800) { /* up*/
					filepos=filepos-1;
					}
				if (key==0x4d00) { /* right*/
					filepos=filepos+22;
					}
				if (key==0x4b00) { /* left*/
					filepos=filepos-22;
					}
				if (key==0x3B00) {
					clrscr();
					printf("\n                    National Book Reader v2.0\n\n");
					printf("              View only russian and english TXT files\n\n");
					printf("            LEFT,RIGHT,UP,DOWN - select file or drive.\n\n");
					printf("                        ENTER - view file.\n\n");
					printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                      (C) 2000 MSW Computing");
					getch();
					clrscr();
					}
				if (filepos<0) filepos=0;
				if (filepos>=i) filepos=i-1;
				if (key==0x11b) break;
			 }
			 if (key==0x11b) break;
			 key=0;
			 if (filepos<5) {
				drive=filepos;
				clrscr();
				drivesel();
				files();
				}
			 if (filepos>4) {
			 clrscr();
			 strcpy(fname,filelist[filepos]);
			 book();
			 }
	 }
	 clrscr();
	 exit(0);
}
void prtmen()
{
	unsigned long pages,fl;
	unsigned int pgs,result;
	FILE *stream;
	zc=0;
	for (xp=0;xp<=4;xp++) {
		xl=xp*15;
		for (yp=1;yp<23;yp++) {
			if (filepos==zc) {
				gotoxy(xl+1,yp);
				cprintf(">%s",filelist[zc]);
				zc=zc+1;
				gotoxy(1,25);
				if (zc-1<5){
				cprintf("Select drive: %-2s                                                          ",filelist[zc-1]);
				}
				else {
				strcpy(fname,filelist[filepos]);
                                	if ((stream=fopen(fname,"r"))==NULL) {
					restorecrtmode();
					fprintf(stderr,"Can't open txt file");
					exit(1);
					}
				result=fseek(stream,0L,SEEK_END);
				fl=ftell(stream);
				result=fseek(stream,0L,SEEK_SET);
				pgs=fl/1920;
				fclose(stream);
				cprintf("%-1s:\\%-12s     Size: %-10lu  ",diskname,filelist[zc-1],fl);
				gotoxy  (60,25);
				cprintf ("%10u pages",pgs);
				}
				}
				else {
				gotoxy(xl+1,yp);
				cprintf(" %s",filelist[zc]);
				zc=zc+1;
				}
			if (zc==i) break;
			}
		if (zc==i) break;
		}
}
void files(void)
{
	struct ffblk ffblk;
	char nam="               ";
	unsigned long siz=0;
	FILE *street;
	textmode(BW80);
	z=findfirst("*.*",&ffblk,0);
	strcpy(filelist[0],"A:\\");
	strcpy(filelist[1],"B:\\");
	strcpy(filelist[2],"C:\\");
	strcpy(filelist[3],"D:\\");
	strcpy(filelist[4],"E:\\");
	for (i=5;i<110;i++) {
		if (z==-1) break;

		nam="                  ";
		p=sprintf(nam,"%s",ffblk.ff_name);
		strcpy(filelist[i],nam);
		filelist[i][13]=0xa;
		z=findnext(&ffblk);
		}
}

void drivesel(void)
{

	dr=setdisk(drive);
	if (dr==0) {
		gotoxy(1,25);
		cprintf("Not ready %s",filelist[filepos]);
		delay(2000);
		setdisk(2);
		}

}









void book(void)
{

      unsigned int key,i;
      unsigned char status,a;
      Initialize();
      Oscill();
      restorecrtmode();
}

void Oscill(void)
{
	unsigned  char bitq,c,s,asdf,pps,result,resoa;
	unsigned int key,h,i,x,y,sda,scl,qsel=0,ksearch,xc,yc,zc,zx,fil,er,keypressed=0;
	unsigned long posit=0,prev[3000],lastz,last;
	unsigned long fl,pageset,pagesel,pconst=1920;
	FILE *stream;
	int pp,ppc,fn,z,dec,sig;
	struct stat buf;
	pp=0;
	prev[pp]=0;

	if ((stream=fopen(fname,"r"))==NULL) {
		restorecrtmode();
		fprintf(stderr,"Can't open txt file");
		exit(1);
		}
	result=fseek(stream,0L,SEEK_END);
	fl=ftell(stream);
	result=fseek(stream,0L,SEEK_SET);
	pgs=fl/1920;
	while (!feof(stream)) {
		cls();
		bitq=0;
		ypos=0; xpos=0;
		lastz=ftell(stream);
		for (h=0;h<24;h++) {
			ypos=h;
			last=ftell(stream);
			for (pps=0;pps<80;pps++) {
				keypressed=0;
				result=fgetc(stream);
				if (result==0xa) break;
					if (result == 0xFF) {
						sprintf(memtxt,"End of file. Press [ESC] for quit or [ARROW LEFT] to Page UP\n");
						fseek(stream,last,SEEK_SET);
						xpos=0;
						ypos=24;
						zprintf();
						while (bioskey(1)==0) ;
						key=bioskey(0);
						if (key==0x5000) { /* down*/
							keypressed=1;
							}
						if (key==0x4800) { /* up*/
							keypressed=2;
							}
						if (key==0x4d00) { /* right*/
							keypressed=3;
							}
						if (key==0x4b00) { /* left*/
							keypressed=4;
							}
						if (key==0x11b) {   /*quit*/
							keypressed=5;
							}
						bitq=1;
						if (keypressed==5|keypressed==4) break; /*sym='q';*/
					}  /*end if EOF*/
			if (keypressed==5|keypressed==4) break;
			if (result<32) {
			memtxt[pps]='.';
			}
			else memtxt[pps]=result;
			} /*end line*/
                        if (keypressed==5|keypressed==4) break;
			memtxt[pps]=0x0a;
			zprintf();
			/*end page*/

			posit=ftell(stream);
			ppc=posit/1920;
			sprintf(memtxt," File: %s       Page: %u       Pages: %u         (C) 1999 MSW     \n ",fname,ppc,pgs);
			xpos=0;
			ypos=24;
			zprintf();
			sprintf(memtxt,"                                                                                ");
			xpos=0;
			}
		while (bitq!=1) {
		 while (bioskey(1)==0) ;
			key=bioskey(0);

			if (key==0x3C00) {

				int pagesel;
				pagesel=ppc;
				xpos=0;
				ypos=24;
				sprintf(memtxt,"Select page:      \n");
				zprintf();
				while (qsel==0) {
					while (bioskey(1)==0) ;
					ksearch=bioskey(0);
					  xpos=14;
					  ypos=24;
					  sprintf(memtxt,"%d      \n",pagesel);
					  zprintf();
					  if (ksearch==0x4800) {
					  pagesel=pagesel+1;
						}
					if (ksearch==0x5000) {
					pagesel=pagesel-1;
					}
				      if (pagesel>pgs) pagesel=pgs;
				      if (pagesel<1) pagesel=0;
				      if (ksearch==0x1c0d) break;
					}
					if (pagesel==0) {
					pageset=0;
					}
					else {
					pageset = pagesel * pconst;
					}
					result=fseek(stream,pageset,SEEK_SET);
					bitq=1;
				}
			if (key==0x3B00) {
				bitq=1;
				key=0;
				Help();
				bioskey(0);
				fseek(stream,lastz,SEEK_SET);
				keypressed=0;
				}

			if (key==0x5000) { /* down*/
				keypressed=1;
				}
			if (key==0x4800) { /* up*/
				keypressed=2;
				}
			if (key==0x4d00) { /* right*/
				keypressed=3;
				}
			if (key==0x4b00) { /* left*/
				keypressed=4;
				}
			if (key==0x11b) {   /*quit*/
				keypressed=5;
				}
		if (keypressed==5) break;
		if (keypressed==4) {
			bitq=1;
			}
		if (keypressed==3) {
			pp=pp+1;
			prev[pp]=posit;
			bitq=1;
			}
		}
		if (keypressed==4) {
			pp=pp-1;
			if (pp<=0) pp=0;
			fseek(stream,prev[pp],SEEK_SET);
			}
		if (keypressed==5) break;

	}
	fclose(stream);

}
void Search(void)
{
}

void Help(void)
{      	xpos=0;
	ypos=0;
	cls();
	sprintf(memtxt,"                        National Book Reader v2.0\n");
	zprintf();
	xpos=0;
	ypos=2;
	sprintf(memtxt,"   LEFT   - page down\n");
	zprintf();
	xpos=0;
	ypos=4;
	sprintf(memtxt,"   RIGHT  - page up\n");
	zprintf();
	xpos=0;
	ypos=6;
	sprintf(memtxt,"   ESC    - exit\n");
	zprintf();
	xpos=0;
	ypos=8;
	sprintf(memtxt,"   F1     - this screen\n");
	zprintf();
	xpos=0;
	ypos=10;
	sprintf(memtxt,"   F2     - go to page\n");
	zprintf();
	sprintf(memtxt,"    UP    - increment value\n");
	xpos=0;
	ypos=12;
	zprintf();
	sprintf(memtxt,"    DOWN  - decrement value\n");
	xpos=0;
	ypos=14;
	zprintf();
	sprintf(memtxt,"    ENTER - select page\n");
	xpos=0;
	ypos=16;
	zprintf();
	xpos=0;
	ypos=24;
	sprintf(memtxt,"                                                 (C) 2000 MSW Home Computing\n");
	zprintf();

}



void Quit(void)
{
	textcolor(WHITE);
        textbackground(BLACK);
	restorecrtmode();
	exit(0);
}
void Initialize(void)
{
  int xasp, yasp, fontst,errorcode;
 GraphDriver = DETECT;
 /*errorcode = registerbgidriver(CGA_driver);
 if(errorcode < 0)  {
	printf("ЋиЁЎЄ  :%s\n",grapherrormessage(errorcode));
	printf("„«п бв ­ў  ­ ¦¬ЁвҐ «оЎго Є« ўЁиг\n");
	getch();
	exit(1);
	} */
  initgraph( &GraphDriver, CGAHI, "" );
  settextstyle(DEFAULT_FONT,HORIZ_DIR,USER_CHAR_SIZE);

  ErrorCode = graphresult();
  if( ErrorCode != grOk ){
    printf(" Graphics System Error\n");
    exit( 1 );
  }
  getpalette( &palette );
  MaxColors = getmaxcolor() + 1;

  MaxX = getmaxx();
  MaxY = getmaxy();
  getaspectratio( &xasp, &yasp );
  AspectRatio = (double)xasp / (double)yasp;
}

void zprintf(void)
{
	unsigned int i,g,z;
	unsigned char l,w;
	z=0; c=memtxt[z];
	while (c!=0xA) {
		c=memtxt[z];
		if (c>=0x20) {
			gettextadr();
			fontadr=(c-0x20)*8;
			for (i=0;i<7;i++) {
				g=fontadr+i;
				l=membl[g];
				pokeb(0xB800,memcoord,l);
				i=i++;
				g=fontadr+i;
				l=membl[g];
				pokeb(0xB800,memcoord+8192,l);
				memcoord=memcoord+80;
				}
			xpos=xpos+1;
			}
		z=z++;
		}


}

void gettextadr(void)
{
	memcoord=xpos+(ypos*320);
}
void cls(void)
{
	unsigned int cl;
	for (cl=0;cl<16384;cl++) pokeb (0xb800,cl,0);
}
void loadfont(void)
{
	unsigned int fil,i;
	char c;
	fil = _open("book.fnt",O_RDONLY);
	if (fil==-1) {
		printf("File BOOK.FNT not found\n");
		abort();
		}
	if ((_read(fil,membl,1792))==-1) {
		printf("Can't load national font file");
		perror("");
		}
	/*fseek(fil,0,SEEK_SET);
	for (i=0;i<1792;i++) {
	fseek(fil,i,SEEK_SET);
	membl[i]=fgetc(fil);
	}
	fclose(fil); */
	_close(fil);
}


> Исходники и программу вы можете взять здесь

  1. Фото взято отсюда

Комментарии (24)


  1. Dabbuger
    18.03.2019 17:06

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


    1. sterr Автор
      18.03.2019 18:02

      Да, забыл указать. Он был рассчитан на 3 батарейки (!) типа АА. Но наличие схемы позволило мне установить аккумы и подключить через стабилизатор схему слаботочного заряда. Батарейки и аккумуляторы ел он хорошо, поэтому аккумуляторы использовались только для сохранения информации в RAM диске. Эксплуатировалась читалка всегда подключенной к сети. Ну или на короткое время для переноса в другое место.


  1. star76
    18.03.2019 17:24

    Моя первая читалка Casio-E125. С 2002 по 2012 пользовался, потом однажды без каких-либо предупреждений превратилась в кирпич (аккум исправен, может bios на флешке стух). Выбросить жалко.


  1. tvr
    18.03.2019 18:25

    Через некоторое время я устроился на работу на спиртзавод дежурным слесарем КИПиА

    Опасная работа, ох опасная, много наших полегло.


    1. sterr Автор
      18.03.2019 22:12

      Нифига не опасная. Замеченных тут же выгоняли без выходного. Воровать — воровали. Но на работе ни-ни. Но и время такое было. Работы нормальной не было, поэтому все держались. Насколько помню уволили всего пару слесарей и пару охранников за все время.


    1. CoolCmd
      18.03.2019 22:30

      Председательствующий: От молодежи завода ученик кладовщика младший штуцерщик на наливе с крепостью до сорока.
      Над трибуной возникает всклокоченная голова.
      Голова: Мы, молодые штуцерщики… (Падает.) Председательствующий. Жаль, что он ушел. Голова (поднимается). Я никогда не забуду своего учителя смесителя Валобуева Григория Григорьевича. Он уже на пенсии в больнице в тяжелом состоянии, но его заветы-указания… Управление штуцером высокого напора он завещал нам, молодым. (Исчезает, затем, вновь появляется.) И мы, молодые… Мы, молодые… (Исчезает.)
      Председательствующий: Ну молодежь, не усидит. Так и мелькает, так и мелькает.


  1. LevOrdabesov
    18.03.2019 18:37
    +1

    А где собственно статья-то?


    1. sterr Автор
      18.03.2019 20:44

      Это просто история об интересном девайсе и его своеобразном применении. А так же о том с чем приходилось сталкиваться имея в руках непонятное по архитектуре устройство с извращенными требованиями по памяти. Ну и для любителей код маленькой читалки.


      1. LevOrdabesov
        18.03.2019 21:17

        Так и расписали бы поподробнее, как в конце-концов решили проблему с запуском ПО, с подключением слаботочного заряда. И фото побольше, хоть текстов на экране. А то всё на самом интересном месте оборвали.


  1. NeoCode
    18.03.2019 20:20
    +1

    И почему сейчас таких девайсов не делают? (по крайней мере массово точно не делают, хотя я вообще не уверен что делают).
    Мощный проц, все современные коммуникации, цветной экран (ну или для разнообразия экран на e-ink или других отражающих технологиях)… Под емкий аккумулятор тоже места хватит в таком форм-факторе. Или как у Samsung Q1 Ultra. Столько простора для творчества дизайнеров, а производят все стандартные планшеты. Эпоха таких форм-факторов и аппаратных клавиатур ушла навсегда?


    1. sterr Автор
      18.03.2019 20:46

      Мощный проц подразумевает питание. Пока вечный двигатель не изобретут, так и будем либо с кирпичами, либо перебежками до розетки. Да и чем любой планшет не аналог? Лепи к нему клавиатуру и будет то же самое.


      1. BelBES
        18.03.2019 21:34

        Планшет с клавиатурой не так удобно из-за немонолитности


        1. sterr Автор
          18.03.2019 22:00

          Ну обычно клава идет с чехлом и получается суррогатный ноутбук. Единственное — кабель торчит.


      1. roboter
        19.03.2019 15:33

        В любом планшете вы всеголишь пользователь с урезанными правами.


    1. BelBES
      18.03.2019 21:33

      У "инди" разработчиков в принцип есть выбор:


      • Gemini PDA
      • GPD Pocket/Win
      • One Mix Yoga

      AAA бренды как-то далеко ушли от такого форм-фактора.


    1. infund
      18.03.2019 21:38

      Планшеты на винде не подходят под это описание?


    1. Gordon01
      19.03.2019 15:49

      Делают, но мало и они никому не нужны. Под них нет ОС, кроме, разве что, андроида, которому нафиг не нужна клавиатура.
      На x86 последний был sony voio p, провалился в продажах, потому что вы, целевая аудитория, рыгали за дороговизну.
      Вроде китайцы сейчас что-то делают.
      Зачем это сегодня, если есть surface pro/surface go?


  1. infund
    18.03.2019 21:13

    В итоге запустил на ББ Turbo C 2.0

    Долго думал, но что такое ББ — так и не догадался.
    В статье явно не хватает скриншота работающей «читалки», чтобы хоть иметь представление о результате. Ясно, что описываются события давно минувших дней, но все же.


    1. sterr Автор
      18.03.2019 21:55

      Ну прошло уже 17-18 лет. Палмтоп еще работает, но вот кабель с софтом давно утерян. Восстанавливать никакого желания нет. И на данный момент эта хреновина неоптимальна для чтения, из-за веса, немобильности, удобства загрузки и т.п. Да и собственно что там смотреть. Меню выбора файла и страница с текстом. В памяти держалась только страница, для экономии. Текст выводился в графическом режиме прямой адресацией в видеопамять, потому что шрифтов русских в видеоадаптере не было.

      ББ — Большой брат, вначале было.


  1. kolu4iy
    19.03.2019 08:48

    У TASM был копаньон — TD, он же turbo debugger. Весь asm на нём прекрасно отлаживался.


  1. EvgeniyNuAfanasievich
    19.03.2019 10:12

    Странно, что никто десятку не порекомендовал накатить попробовать…


  1. dlinyj
    19.03.2019 11:13

    Да. Хотелось бы подробности программы. Загрузку шрифтов и т.п. Я так код посмотрел, код годный, хороший. Но подробностей мало.

    Железки видать уже нет?


  1. amarao
    19.03.2019 12:28

    Выглядит офигенно. Если в неё засунуть современное железо и экран, получится отличная машинка. Ещё клитор от lenovo для замены мыши — и готовый КПК.


    1. NeuroHunter
      19.03.2019 13:34

      А чуть выше же привели примеры современных альтернатив. В каком-то даже есть «клитор от Lenovo».
      Хотя, как пользователь Gemini PDA, могу сказать — как читалка это очень неудобный агрегат.