Карманный компьютер Psion Organizer II XP был выпущен одноименной британской компанией Psion в 1986 году. Он стал успешным представителем линейки Psion Organizer, в которой первенцем был Organizer I, сошедший с конвейера в 1984 году. Последним представителем серии стал Organizer II LZ появившийся в продаже в 1989.
Psion Organizer часто титулуется первым в мире PDA (то, что у нас называлось КПК) и хотя это утверждение на мой взгляд спорно, Органайзеры действительно имели уникальные особенности для карманных компьютеров тех лет.
Краткие характеристики
Год выпуска: 1986
ЦПУ: 8-битный CMOS Hitachi HD6303X работающий на частоте 0.92МГц
ПЗУ: 32 или 64КБ (для многоязычной версии)
ОЗУ: 16 или 32КБ
Экран: ЖКИ, 2 строки по 16 символов.
Питание: 9-вольтовая батарея типа «крона» или от адаптера (в комплект не входил)
Клавиатура: 36-кнопочная, раскладка «ABC»
Размер: 142 x 78 x 29мм (с закрытой защитной крышкой)
Вес: 250г
Цена: 139 фунтов на старте продаж
Небольшая предыстория
Экземпляр который вы видите на фотографиях был куплен на ebay за скромную (для работающего устройства 1986г.) сумму в 30$. Такая низкая стоимость связана по-видимому с былой популярностью устройства (было продано более миллиона устройств этой линейки) а также его живучестью. На удивление, лот был помечен как «BRAND NEW», на сколько это соответствует действительности я судить не берусь, но устройство действительно приехало в близком к идеальному состоянию.
Обзор
Упаковка существенно потрепана временем. Внутри под защитой пенопласта располагается сам Psion, инструкция по эксплуатации, описание гарантийных обязательств и незаполненный гарантийный талон. К сожалению, инструкция и гарантийный талон склеились и в процессе разъединения обложка инструкции была испорчена, коробка видимо хранилась в месте с избыточной влажностью.
Корпус устройства выполнен из очень прочного пластика, это отмечается чуть ли не в каждом описании. Мне довелось испытать его прочность на практике — случайно уронил со стола на ламинат, высота ~75см, найти следов падения мне так и не удалось. Корпус Psion имеет еще одну особенность — сдвигающаяся вниз крышка защищающая клавиатуру и подключаемые модули памяти. Крышка съемная, так Psion выглядит без нее:
Такое внимание к прочности объясняется тем, что устройство было во многом нацелено на применение в бизнесе. На его основе, например, были широко распространены мобильные POS-терминалы; Sony использовала Psion'ы в своих европейских сервисных центрах; они применялись при геодезических работах, и в других сферах деятельности.
Размеры Psion'а примерно соответствуют нынешним 5" телефонам. Вот, например, в сравнении с Nexus 5X:
Телефон, правда, несколько тоньше.
Экран — знакосинтезирующий ЖК индикатор, имеет 2 строки по 16 символов. Разрешение символа 5x8. К сожалению, прямой доступ к отдельным пикселям отсутствует, что существенно ограничивает графические возможности (если конечно вообще можно рассуждать о графических возможностях имея 80x16 пикселей), при этом в таблице символов напрочь отсутствует псевдографика. Но разработчики оставили лазейку — 8 переопределяемых символов, благодаря чему 320 пикселей единовременно в нашем полном распоряжении.
Если у вас появился эффект дежавю, то не удивительно. Контроллер дисплея построен на базе Hitachi HD44780, и сама матрица и контроллер а так же их аналоги активно используются в DYI (и не только) по сей день, тот самый «зеленый экран», схемы подключения которого к Arduino можно найти повсюду, его прямой потомок.
Клавиатура — 36-кнопочная мембранная, раскладка «ABC». Каждая алфавитно-цифровая кнопка отвечает за ввод двух символов, переключение между ними классическое — с зажатой SHIFT, или комбинацией SHIFT+NUM. Кроме Алфавитно-цифровых клавиш, на клавиатуре имеются кнопки управления курсором; стандартные SHIFT, DEL, SPACE, EXE (аналог Enter); кнопка ON, которая и спустя 30 лет исправно включает устройство, во включенном состоянии она выполняет функции Esc; кнопка MODE вызывает что-то вроде контекстного меню.
Несколько неожиданным может показаться отсутствие кнопки выключения, отключить устройство можно только из главного меню или, как советуют в инструкции, не выключать вовсе, устройство само перейдет в режим ожидания и после включения пользователь начнет работу с того места где закончил. Также можно отметить отсутствие таких распространенных знаков препинания, как восклицательный и вопросительный, немного странно для устройства с функцией записной книжки.
Вытянутый по вертикали «калькуляторный» форм-фактор, на мой взгляд, выигрывает у горизонтального, который был гораздо более распространен среди карманных компьютеров 80-х годов, печатать можно хоть на ходу.
На задней стороне корпуса расположены два слота под модули памяти. К сожалению, в стандартный комплект продажи они не входили, вместо них у меня просто две заглушки.
Модули памяти существовали нескольких видов:
Datapack — на микросхеме EPROM, на нее пользователь мог записывать данные для долговременного хранения, но удаляемые файлы просто маркировались как удаленные, очистить память можно было только ультрафиолетовым облучением, для чего приобреталось специальное устройство (наверно проще было купить новый модуль). Вплоть до конца 90-х сообщество пользователей Psion публиковало адреса людей по всей Европе, которым можно было отправить модуль памяти для стирания, оплатив только почтовые расходы. Объем памяти от 8 до 128КБ. Эти модули были наиболее популярные.
С EPROM внутри так же распространялись так называемые Programpack — модули с готовым ПО, хотя некоторые из них использовали нестираемые PROM. Programpack'и выпускал как Psion, так и многочисленные независимые разработчики. Программы были самыми разнообразными — игры, словари и переводчики, файловый менеджер, электронные таблицы и многое другое, даже ассемблер.
Слева на право: 64КБ Datapack, 32КБ Rampak, 256КБ Flashpak. Фотографии взяты с сайта www.jaapsch.net
Rampack — использовались энергозависимые SRAM, их можно было записывать и стирать, но время хранения ограничивалось несколькими годами, внутри была несьемная батарея а стоимость модулей была существенно выше чем у datapack. Rampack'и были размером вплоть до 512КБ
Flashpack — как ясно из названия, внутри чипы флеш-памяти NOR-типа, правда появились эти модули значительно позже начала продаж Organizer II, в 1986 году микросхем такого типа еще не было в продаже. Из-за этого они поддерживались не полностью.
Питается устройство от одной 9-вольтовой батареи 6F22 или проще от «Кроны». Еще параллельно с покупкой Органайзера я заказал пару аккумуляторов такого типоразмера заряжаемых по USB — не хотелось разоряться на батарейки. Эти аккумуляторы я так ни разу не использовал, обычной алкалиновой кроны хватило на все мои изыскания. Судя по отзывам пользователей, при активной работе батарейку нужно было менять раз в пару месяцев.
Сверху, под защитой сдвигаемой шторки, расположен разъем для подключения внешних устройств.
К сожалению, ни одного внешнего устройства у меня нет, поэтому отмечу только, что для Органайзера было выпущено большое количество периферии как самим Psion, так и сторонними производителями. Среди них были, например, принтеры, сканеры штрих-кодов, модем, пейджер, считыватель магнитных карт, конвертеры на RS232, повербанк и многие другие устройства. Интересной особенностью было то, что при подключении устройства, Psion автоматически запускал содержащийся в его памяти код (если она была), таким образом подключая, например, сканер штрих-кодов, пользователю автоматически добавлялись нужные для работы с ним программы и дополнительные функции для OPL.
Слева на право: модем, пейджер, сканер штрих-кода, термопринтер. Фотографии взяты с сайта www.jaapsch.net
Гикпорн
Конечно, Psion был вскрыт.
Судя по штампам на платах, мой экземпляр собран в конце 87 года. Пьезодинамик сильно окислен, но, к счастью, это единственная деталь со следами коррозии.
Все компоненты расположены на двух платах соединенных шлейфом, сверху плата питания, которая так же содержит разъемы для подключения периферии, снизу главная плата, на которой расположено 6 микросхем — микропроцессор, контроллеры дисплея, 32КБ ОЗУ и 32КБ ПЗУ и одна полу-заказная многофункциональная микросхема.
Сверху 2 чипа — Hitachi DG44100H и HD44780A00. HD44780 основная микросхема контроллера дисплея, но, поскольку она может управлять только 2 строками по 8 символов, на схеме присутствует вспомогательная DG44100H. Как я уже писал, контроллеры на базе HD44780 до сих пор широко распространены.
Чуть ниже Hitachi HD6303XF. Это 8-битный CMOS микропроцессор (точнее MPU) из семейства HD6301-HD6303 которые были обратно совместимы с известным Motorola 6800. Процессор работает на частоте 0.9216 МГц.
Еще ниже, слева находится микросхема ОЗУ — HM62256LFP-12T, обещанные 32КБ SRAM-памяти.
Справа от нее полу-кастомный чип, который выполняет сразу несколько функций: управляет включением и выключением процессора, опрашивает клавиатуру, обеспечивает функционал часов реального времени и некоторые другие.
И в самом низу микросхема, от недавно основанной в то время компании Atmel, AT27C256 — это чип однократно программируемой памяти (OTP) EPROM объемом 32КБ.
Вот вам еще немного микропроцессора с бокэшечкой:
Коллаж обратной стороны обеих плат:
Тетрис
Еще покупая Органайзер, была мысль что-нибудь для него написать. Причем изначально хотел полностью погрузиться в древность и писать прямо на нем, поэтому покупку Com-переходника даже не рассматривал, о чем быстро пожалел — программировать на экране в 2 строчки очень сложно, возникает что-то подобное клаустрофобии. В итоге пришлось открывать Notepad++, но тут остро встал вопрос переноса кода — печатать на калькуляторной ABC клавиатуре после некоторого привыкания конечно можно, но сложно, поэтому отладку тоже решено было перенести на компьютер.
Для Psion Organizer II существовал официальный коммерчески распространяемый SDK, включающий редактор кода, транслятор, отладчик, симулятор и утилиту для создания образа модулей памяти.
Слева редактор, справа процесс отладки
Все в нем хорошо, но, из-за того, что в комплекте симулятор а не полноценный эмулятор, мы не можем работать с низкоуровневыми функциями вроде peek, poke и запускать машинный код, из-за чего тестировать программы которые работают с переопределенными символами (User Defined Graphics или UDG, те самые 320 пикселей) становится проблематично.
К счастью для клавиатуры Psion'а и для моих пальцев, в 98 году независимым разработчиком Полом Робсоном (Paul Robson) был написан полноценный эмулятор всей линейки Psion Organizer II, образы для которого официально предоставил сам Psion Inc.
Этот эмулятор в связке с транслятором из официального SDK я и использовал для разработки.
О средствах разработки рассказал, теперь кратко про сам язык OPL.
OPL (Organiser Programming Language) — это BASIC-подобный интерпретируемый язык программирования. Встроенный в Органайзер транслятор создает байт-код, который уже выполняется интерпретатором, за счет этого достигается относительно высокая скорость работы программ. Отличительной особенностью OPL является возможность выполнения машинных инструкций «из коробки», благодаря этому устройство в полном распоряжении разработчика.
Итак, после некоторых раздумий о том, что бы написать под Psion, выбор пал на Тетрис (да, очень оригинально). Во-первых, за 30 лет его так и не написали для двухстрочного Psion'а (может быть он есть, но я нашел только реализацию для четырехстрочной модели LZ). Во-вторых, можно использовать графические возможности устройства и главное их достаточно (почти). Были некоторые сомнения на счет того, хватит ли скорости работы интерпретируемого языка для Тетриса на таком низкопроизводительном устройстве, но первые же тесты показали, что скорости будет достаточно и это вполне подтвердилось — Тетрис был полностью написан на OPL и только в конце, больше для интереса, пара самых нагруженных участков по отрисовке была переписана в машинных кодах.
Основным моментом было рисовать «стакан» с фигурами так, чтобы не было заметно отступов между символами, для этого я каждый символ поделил на шесть квадратов 2x2 пикселя, в таком виде получается равномерно заполнить все игровое поле красивыми квадратиками (like a brick game), по такому типу:
Но тут нас ждет неприятный момент — ограничение на 8 UDG, этого хватило бы только на игровое поле размером 6x8 квадратов, явно маловато. Поэтому добавил в игру «фичу» — «туман войны». Рисуем сверху вниз все игровое поле и падающую фигуру пока есть свободные UDG а все остальное заполняем символом "█", вот так:
Теперь можем сделать высоту стакана почти канонической — 19 рядов (20-й ряд занят отрисовкой дна стакана, чтобы отделить игровое поле от информационного текста), ширина выходит всего 6 кирпичиков вместо положенных 10, но тут ничего не поделаешь. Оставшееся слева свободное место заполняем количеством набранных очков, уровнем и подсказкой о следующей фигуре. К сожалению UDG у нас уже не остается и пришлось следующую фигуру отображать буквами (я раньше не знал, но оказывается для фигур Тетриса есть вполне устоявшиеся буквенные обозначения «OISZLJT»), в итоге игра приобретает следующий вид:
Ну и в качестве вишенки нарисовал заставку, вдохновляясь картинкой из GameBoy-версии Тетриса:
Мм… в свое оправдание лишь отмечу, что у меня было очень мало пикселей!
Подробно останавливаться на коде я не буду, там ничего особенно интересного. Отмечу только несколько специфичных моментов с которыми я столкнулся:
— OPL далеко не рекордсмен по компактности кода, все эти % $ в названиях переменных как у Бэйсика, отсутствие цикла for, отсутствие возможности инициализации переменных (особенно массивов) при их описании приводят к сильной избыточности писанины. А в голове я всегда держал тот момент, что каждые 50 символов — это дополнительная минута к вводу кода в Psion, поэтому приходилось жестко экономить буквы, в итоге уложился в 3.5КБ («всего-то» час-полтора на ручной ввод);
— Хотя в OPL есть поддержка процедур и функций, но реализована она специфически — каждая процедура описывается в отдельном файле и доступна из любой другой программы (которые и есть процедуры). Это наверно удобно для использования в мелких расчетных подпрограммах пользователя, но довольно не удобно при написании игры, части которой явно не будут использоваться повторно, а накладные расходы на вызов функций существенны. К тому же несколько файлов менее удобно синхронизировать вручную. Это вынудило меня отказаться от функций и ограничиться GOTO (первая программа в которой я использовал этот оператор, такой вот опыт);
— Заполнить массив можно только последовательным присваиванием значений каждому элементу. Это приводило к ужасным вещам вроде «f%(2)=24 :f%(3)=24 :f%(6)=24»… и далее до 112 индекса (для хранения фигур). В массивах так же нужно хранить машинный код и конечно заставку. Руками на клавиатуре Psion'а это вводить нельзя, психика не железная, пришлось такие вещи хранить в виде строк и конвертировать их при запуске программы.
TETRIS:
local brd%(11),bra%,cur%(11),cra%,f$(112),f%
local nf%,row%,x%,y%,a%,px%,py%,pa%
local i%,j%,k%,b%
local un%,um%,s$(32),s%,mc$(255),mc%
local tmr%,scr,scr$(47),lvl%,lns%
local kbdl%,bzmt%,mute%,kbmt%
REM Машинный код в виде hex-строки, за ней идет конвертация в "нормальную" последовательность байт
mc$="040404CE00030436378401C4014848481B16581BC6027D01802BFBB701815A2EF52D044F0926EF333226DB39"
mc%=ADDR(mc$)+1
do
i%=PEEKB(mc%)-48 :j%=PEEKB(mc%+1)-48
mc$=mc$+CHR$((i%-i%/16*7)*16+j%-j%/16*7)
mc%=mc%+2
until i%*10+j%=39
REM Меняем системные переменные - отключаем штатный звук клавиш и уменьшаем время задержки при удержании клавиши, перед завершением программы их нужно восстановить обратно
kbdl%=PEEKB($77)
POKEB $77,3
bzmt%=PEEKB($A4)
kbmt%=PEEKB($20C0)
POKEB $20C0,0
ONERR EXIT::
REM Храним заставку в виде строки, символы подобраны с учетом возможности напечатать на клавиатуре Psion'а
f$="04000001>>44zg>m0002000 000000270004>oo>376539llg>mkvo0o8L<Lhb72"
POKEB $180,64
i%=0
do
i%=i%+1
POKEB $181,PEEKB(ADDR(f$)+i%)-16 AND $1F
until i%=64
CLS :AT 10,1 :PRINT "* ."+CHR$(0)+CHR$(1)+CHR$(2),"TETRIS ",CHR$(3)+CHR$(4)+CHR$(5)+CHR$(6)+CHR$(7)+CHR$(1)
GET
MENU::
b%=MENU("START,INFO,QUIT")
if b%=2
AT 3,2 :PRINT "by azya, 2017"
VIEW(1,"Q - quit, P - pause, Arrows - move, A - rotate, M - mute") :goto MENU::
elseif b%=3
goto EXIT::
endif
REM Массив фигур с поворотами в виде строки, для получения "нормального" байта при обращении будем делать конъюнкцию с 0F
f$="06600660066006600o0022220o00222203602310036023100630132006301320074022301700622007103220470022600720232027002620"
lns%=0 :scr=0
bra%=ADDR(brd%())
cra%=ADDR(cur%())
RANDOMIZE PEEKW($20CB)
nf%=INT(RND*7)
brd%(10)=$00FF
s%=ADDR(s$)
NEWF::
row%=0
f%=ADDR(f$)+1+nf%*16
um%=5+(nf%=0)
tmr%=PEEKW($20CB)
nf%=INT(RND*7)
x%=4 :y%=0 :a%=0 :py%=0
REM Удаляем заполненные строки
i%=18 :b%=18
do
POKEB bra%+b%,PEEKB(bra%+i%)+PEEKB(cra%+i%) OR $81
POKEB cra%+b%,0
if PEEKB(bra%+b%)<>$FF
b%=b%-1
endif
i%=i%-1
until i%=0
REM Подсчитываем очки
if b%>0
scr=scr+40-60*(b%>1)-200*(b%>2)-900*(b%>3)
lns%=lns%+b%
if lns%<151
lvl%=lns%/10
endif
i%=800
do
BEEP 17,i% :BEEP 15,i%-200
i%=i%+100
until i%>1100
endif
REM Рисуем фон
s$=REPT$(" ",9)+GEN$(1000000+scr,7)+REPT$(" ",10)+CHR$(91)
POKEB s%+10,32
s$=s$+MID$("OISZLJT",nf%+1,1)+CHR$(93)+GEN$(100+lvl%,3)
POKEB s%+30,%L
AT 1,1 :PRINT s$
un%=0 :i%=1
POKEB $180,64
do
j%=0
do
if brd%(i%) AND $E0E*(j%*7+1)
POKEB s%+i%+16*j%,255
if un%<um%
REM Выполняем код описанный в mc$
USR(mc%+3-3*j%,brd%(i%))
POKEB s%+i%+16*j%,un%
un%=un%+1
endif
endif
j%=j%+1
until j%>1
i%=i%+1
until i%>10
while KEY :endwh
MAIN::
POKEB cra%+py%,0
REM Проверяем, нет ли коллизий после изменения состояния фигуры, если нет то добавляем фигуру в стакан, если есть то действуем исходя из ситуации
i%=y%+4
do
i%=i%-1
b%=(PEEKB(f%+a%-y%+i%) AND $F)*x%
if PEEKB(bra%+i%) AND b%
if y%=0 AND x%=4
goto GOVR::
elseif b% AND $80
x%=x%/2
elseif b% AND 1
x%=x%*2
else
row%=y%>py%
x%=px% :y%=py% :a%=pa%
endif
goto MAIN::
endif
POKEB cra%+i%, b%
until i%=y%
px%=x% :py%=y% :pa%=a%
if row%
i%=2000
do
BEEP 2,i%
i%=i%+200
until i%>4400
goto NEWF::
endif
REM Рисуем фигуру
un%=um%
i%=y%/2+1
AT 1,1 :PRINT s$
do
b%=cur%(i%) OR brd%(i%)
if cur%(i%) AND $E0E
POKEB $180,64+un%*8
USR(mc%+3,b%)
AT i%,1 :POKEB $181,un%
un%=un%+1
endif
if cur%(i%) AND $7070
POKEB $180,64+un%*8
USR(mc%,b%)
AT i%,2 :POKEB $181,un%
un%=un%+1
endif
i%=i%+1
until cur%(i%)=0
REM Цикл опроса клавиатуры и анимации падения фигуры
do
k%=KEY AND 95
if k%=0
PAUSE -1
endif
if PEEKW($20CB)-tmr%>17-lvl%
tmr%=PEEKW($20CB)
y%=y%+1
goto MAIN::
elseif k%
while KEY :endwh
if k%=6
scr=scr+1
y%=y%+1
elseif k%=3
BEEP 15,500
x%=x%-x%/2
elseif k%=4
BEEP 15,500
x%=x%+x%
elseif k%=%A
BEEP 15,750
a%=a%+4 AND 15
elseif k%=%P
AT 1,1 :PRINT "PAUSE" :GET
elseif k%=%M
mute%=-(mute%-1)
POKEB $A4,mute%
elseif k%=%Q
BREAK
endif
goto MAIN::
endif
until 0
GOVR::
scr$="Scores:"+GEN$(scr,6)+" Level:"+GEN$(lvl%,2)+" Lines:"+GEN$(lns%,6)
if k%<>%Q
scr$="GAME OVER"+CHR$(33)+" "+scr$
endif
do
b%=DISP(1,scr$+CHR$(9)+" QUIT GAME"+CHR$(63)+" Y/N ") and 95
if b%=%N AND k%=%Q
goto MAIN::
elseif b%=%N
TETRIS:
endif
until b%=%Y
EXIT::
POKEB $77,kbdl%
POKEB $A4,bzmt%
POKEB $20C0,kbmt%
И напоследок видео того, что получилось:
Подборка ссылок:
www.jaapsch.net/psion — очень большая коллекция документов, фотографий и программ для всех моделей Psion Organizer.
archive.psion2.org/org2/org2.htm — зеркало оригинального сайта сообщества пользователей Psion Organizer, который был закрыт в 2002 году.
forum.psion2.org — форум пользователей и разработчиков.
Комплект разработки — собрал в один архив инструменты которыми пользовался при разработке.
Автор: aka Feya