Я всегда любил читать. Начиная с детского сада. Потом в школе я перечитал почти всю библиотеку. Когда пошел на работу, в лихие девяностые, покупал на рынках кучу всяких книг. Время было тяжелое. Многие уезжали в Германию на ПМЖ. Уехал и мой друг. Потом через несколько лет в конце девяностых прислал посылку в которой кроме невиданных заморских сладостей лежало 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 диске. Да и нормальных аккумуляторов в то время сложно было найти, поэтому эксплуатировалась читалка всегда подключенной к сети. Ну или на короткое время от аккумуляторов для переноса в другое место.
→ Исходники и программу вы можете взять здесь
Именно таких:

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

Радости моей не было предела!
Но посидев, и покрутив в руках эту вещицу, было непонятно для чего ее можно использовать. В этом палмтопе были предустановлены приложения в основном для бизнеса — календарь, записная книжка, файловый менеджер. Разъемы Com и LPT были проприетарными. Миниатюрные, похожие на своих полноценных собратьев, но без штырьков, а ножевые, подобные PCI или PCIe. Интернет в то время
Казалось бы, проблема решена, закачивай программы и пользуйся в свое удовольствие. Помучался я неделю. Перебрал всевозможные программы, в основном игрушки. Но в силу отступления от классического формата 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); }
→ Исходники и программу вы можете взять здесь
