WDC 65C02 - WDC 65C02 - Wikipedia

W65C02S микропроцессор в корпусе ПДИП-40.

В Центр западного дизайна (WDC) 65C02 микропроцессор это улучшенный CMOS версия популярного nMOS -основан 8 бит Технология MOS 6502. Хотя 65C02 исправил несколько проблем в исходном 6502 и добавил несколько новых инструкций, его основной особенностью было значительно сниженное энергопотребление, примерно в 10-20 раз меньше, чем у NMOS 6502, работающего на той же скорости.[1] Сниженное энергопотребление сделало 65C02 полезным в портативный компьютер роли и микроконтроллер системы в промышленных условиях. Он использовался в некоторых домашние компьютеры, а также в встроенный приложения, включая имплантированные устройства медицинского назначения.

Разработка началась в 1981 году.[а] а образцы были выпущены в начале 1983 года.[b] WDC предоставила лицензию на разработку Synertek, NCR, GTE, и Rockwell Semiconductor. В первую очередь Роквелл интересовался рынком встраиваемых систем и попросил добавить несколько новых команд, чтобы помочь в этой роли. Позже они были скопированы обратно в базовую версию, после чего WDC добавила две новые собственные команды для создания W65C02. Саньо позже лицензировал дизайн, и Сейко Эпсон произвел дальнейшую модифицированную версию как HuC6280.

Ранние версии использовали 40-контактный DIP-корпус и были доступны в версиях 1, 2 и 4 МГц. Более поздние версии были произведены в PLCC и QFP пакеты, а также PDIP, и с гораздо более высокими тактовыми частотами. Текущая версия от WDC, W65C02S-14 имеет полностью статическое ядро ​​и официально работает на частоте до 14 МГц при питании от 5 вольт.

Введение и особенности

65C02 - недорогой универсальный 8 бит микропроцессор (8 бит регистры и шина данных ) с 16 бит счетчик команд и адресная шина. Набор регистров небольшой, с одним 8-битным аккумулятор (A), два 8-битных индексные регистры (X и Y), 8-битный регистр состояния (P) и 16-битный счетчик программ (PC). Помимо единственного аккумулятора, первые 256 байт ОЗУ, «нулевая страница» ($0000 к $ 00FF), обеспечивают более быстрый доступ за счет режимов адресации, в которых используется 8-битный адрес памяти вместо 16-битного. В куча находится в следующих 256 байтах на первой странице (от $ 0100 до $ 01FF) и не может быть перемещен или расширен. Стек растет вниз вместе с указатель стека (S), начиная с $ 01FF и уменьшаясь по мере роста стека.[2] Имеет переменную длину Набор инструкций, варьируясь от одного до трех байтов на инструкцию.[1]

Базовая архитектура 65C02 идентична оригинальной 6502 и может рассматриваться как реализация этой конструкции с низким энергопотреблением. На частоте 1 МГц, самой популярной для оригинального 6502, 65C02 требует всего 20 мВт, в то время как исходный использует 450 мВт, что более чем в двадцать раз меньше.[3] Оптимизация ядра вручную и низкое энергопотребление делают 65C02 хорошо подходящим для работы с низким энергопотреблением. система на кристалле (SoC) конструкции.[1]

А Verilog Модель описания оборудования доступна для проектирования ядра W65C02S в специализированная интегральная схема (ASIC) или программируемая вентильная матрица (ПЛИС).[4] Как это часто бывает в полупроводниковой промышленности, WDC предлагает систему разработки, которая включает доска разработчика, внутрисхемный эмулятор (ICE) и система разработки программного обеспечения.[5]

В W65C02S – 14 это серийная версия по состоянию на 2020 год, и доступен в PDIP, PLCC и QFP пакеты. Максимальная официально поддерживаемая тактовая частота Ø2 (первичная) составляет 14МГц при работе от 5 вольт, обозначается суффиксом -14 номера детали (любители разработали 65C02 домашнее пиво системы, которые работают быстрее официального рейтинга). Обозначение "S" указывает на то, что деталь имеет полностью статическое ядро, функция, которая позволяет замедлить или полностью остановить Ø2 в высоком или низком состоянии без потери данных.[6] Типичные микропроцессоры, не реализованные в CMOS, имеют динамические ядра и будут терять содержимое своих внутренних регистров (и, следовательно, давать сбой), если они не будут постоянно синхронизироваться со скоростью между некоторыми минимальными и максимальными указанными значениями.

65C02 регистры
15141312111009080706050403020100(битовая позиция)
Основные регистры
 .AАнакопитель
Индексные регистры
 .ИКСИкс Индексный регистр
 .YY Индексный регистр
00000001SPSзакрепка пласточка
Счетчик команд
ПКппрограмма Cвстречный
Регистр статуса
 NV-BDяZCSтатус рнапарник

Общие логические особенности

Фотография кристалла микроконтроллера Sitronix ST2064B со встроенным W65C02S ядро в правом верхнем углу

Логические особенности

Электрические характеристики

  • Поставлять Напряжение указано от 1,71 В до 5,25 В
  • Потребление тока (ядро) 0,15 и 1,5 мА на МГц при 1,89 В и 5,25 В соответственно
  • Набор команд переменной длины, позволяющий оптимизировать размер кода для процессоров с набором команд фиксированной длины, приводит к экономии энергии
  • От корки до корки статическая схема позволяет останавливать часы для экономии энергии

Особенности синхронизации

W65C02S может работать при любом удобном напряжении питания (ВDD) от 1,8 до 5 В (± 5%). В техническая спецификация В таблице характеристик переменного тока приведены рабочие характеристики при 5 В при 14 МГц, 3,3 В или 3 В при 8 МГц, 2,5 В при 4 МГц и 1,8 В при 2 МГц. Эта информация может быть артефактом из более ранней таблицы данных, поскольку график показывает, что типичные устройства способны работать на более высоких скоростях, чем указано в таблице характеристик переменного тока, и что надежная работа на 20 МГц должна быть легко достижима с VDD на 5 вольт, если это позволяет поддерживающее оборудование.

Поддержка W65C02S произвольной тактовой частоты позволяет использовать тактовую частоту, которая работает с частотой, идеальной для какой-либо другой части системы, например 13,5 МГц (частота дискретизации яркости цифрового SDTV), 14,31818 МГц (частота цветовой несущей NTSC × 4), 14,75 МГц (квадратные пиксели PAL), 14,7456 (кристалл скорости передачи) и т. Д., Пока VDD достаточно, чтобы поддерживать частоту. Дизайнер Билл Менш указал, что FМАКСИМУМ зависит от внешних факторов, таких как емкостная нагрузка на контакты микропроцессора. Минимизация нагрузки за счет использования коротких сигнальных дорожек и минимального количества устройств помогает поднять FМАКСИМУМ. Пакеты PLCC и QFP имеют меньшую межконтактную емкость, чем корпус PDIP, и более экономичны в использовании печатная плата Космос.

WDC сообщил, что реализация W65C02S на базе FPGA успешно работает на частоте 200 МГц.

Сравнение с NMOS 6502

Базовая архитектура

Хотя 65C02 в основном можно рассматривать как маломощный 6502, он также исправляет несколько ошибок, обнаруженных в оригинале, и добавляет новые инструкции, режимы адресации и функции, которые могут помочь программисту в написании небольших и быстро выполняющихся программ. Подсчитано, что средняя программа на языке ассемблера 6502 может быть уменьшена на 10-15 процентов на 65C02 и получить аналогичное улучшение производительности, в основном за счет предотвращения доступа к памяти за счет использования меньшего количества инструкций для выполнения данной задачи.[1]

Недокументированные инструкции удалены

Исходный 6502 имел 56 инструкций, которые в сочетании с различными режимами адресации давали в общей сложности 151 команду. коды операций из возможных 256 8-битных шаблонов кода операции. Остальные 105 неиспользуемых кодов операций не были определены, при этом набор кодов с младшими 4-мя битами с 3, 7, B или F остался полностью неиспользованным, а код с младшим 2-м кодом имел только один код операции.[7]

6502 был известен тем, что некоторые из этих оставшихся кодов действительно выполняли действия. Из-за того, как работает декодер инструкций 6502, простая установка определенных битов в коде операции может привести к выполнению части обработки инструкций. Некоторые из этих кодов операций сразу вызвали сбой процессора, в то время как другие выполняли полезные функции и даже получали от пользователей неофициальную мнемонику ассемблера.[8]

65C02 добавил ряд новых кодов операций, которые использовали ряд этих ранее "недокументированных команд" слотов, например, $ FF теперь использовался для новых BBS инструкция (см. ниже). Те, что остались по-настоящему неиспользованными, были настроены на выполнение NOPс. Программы, использующие эти коды, не будут работать на 65C02, но эти коды всегда документировались как неработающие и не должны были использоваться.[1]

Исправление ошибок

Первоначальный 6502 имел несколько ошибок при запуске. Ранние версии процессора имели дефект ROR (повернуть вправо) инструкция, которая выдает MOS Technology, не документируя инструкцию. ROR был исправлен в самом начале производственного цикла и не был проблемой для подавляющего большинства компьютеров, использующих процессор.[9]

Напротив, печально известная ошибка, которая присутствует во всех вариантах NMOS 6502, связана с инструкцией перехода (JMP) когда используешь косвенная адресация. В этом режиме адресации целевой адрес JMP инструкция извлекается из памяти (вектор перехода), а не является операндом JMP инструкция. Например, JMP (1234 долл. США) будет извлекать значение из ячеек памяти $ 1234 (младший байт) и $ 1235 (старший байт) и загружать эти значения в счетчик команд, что затем заставит процессор продолжить выполнение по адресу, хранящемуся в векторе перехода.

Ошибка возникает, когда адрес вектора заканчивается на $ FF, что является границей страница памяти. В этом случае, JMP будет извлекать наиболее значимый байт целевого адреса из $ 00 исходной страницы, а не из $ 00 новой страницы. Следовательно JMP (12 долларов США) получит младший байт целевого адреса в $ 12FF, а старший байт целевого адреса - в $ 1200, а не в $ 1300. 65C02 исправил эту проблему.[1]

Состояние флага (D) ecimal в регистре состояния NMOS 6502 больше похоже на недосмотр, чем на ошибку, после перезагрузить или же прерывать. Это означает, что программисты должны установить флаг на известное значение, чтобы избежать ошибок, связанных с арифметическими операциями. В результате получается CLD инструкция (CLear Decimal) почти во всех 6502 обработчики прерываний, а также в начале кода сброса. 65C02 автоматически сбрасывает этот флаг после помещения регистра состояния в стек в ответ на любое прерывание или в ответ на аппаратный сброс, тем самым переводя процессор обратно в режим двоичной арифметики.[10]

В течение десятичный режим арифметика, NMOS 6502 обновит флаги (N) egative, o (V) erflow и (Z) ero, чтобы отразить результат двоичной арифметики, то есть флаги отражают результат, вычисленный до того, как процессор выполнит десятичную коррекцию. Напротив, 65C02 устанавливает эти флаги в соответствии с результатом десятичной арифметики за счет дополнительного тактового цикла на арифметическую инструкцию.[10]

При выполнении инструкции чтения-изменения-записи (R-M-W), такой как INC адрес, все варианты NMOS будут выполнять двойную запись адрес, сначала перезаписывая текущее значение, найденное в адрес а затем записать измененное значение. Такое поведение может привести к трудностям для устранения ошибок, если адрес это аппаратный регистр. 65C02 вместо этого выполняет двойное чтение адрес, за которым следует одна запись.

При выполнении индексированной адресации, если индексирование пересекает границу страницы, все варианты NMOS будут считываться с недопустимого адреса перед доступом к правильному адресу. Как и в случае с инструкцией R-M-W, такое поведение может вызвать проблемы при доступе к аппаратным регистрам через индексацию. 65C02 исправил эту проблему, выполнив фиктивное чтение кода операции инструкции, когда индексирование пересекает границу страницы. Однако это исправление привело к появлению новой ошибки, которая возникает, когда базовый адрес находится на четной границе страницы (что означает, что индексация никогда не перейдет на следующую страницу). С новой ошибкой фиктивное чтение выполняется по базовому адресу до индексации, так что LDA $ 1200, X выполнит фиктивное чтение на 1200 долларов до того, как значение X будет добавлено к 1200 долларам. Опять же, при индексации адресов аппаратных регистров эта ошибка может привести к неопределенному поведению.

Если NMOS 6502 получает код операции BRK (программное прерывание) одновременно с аппаратным прерыванием, BRK игнорируется, поскольку процессор реагирует на прерывание. 65C02 правильно обрабатывает эту ситуацию, обслуживая прерывание и затем выполняя BRK.

Новые режимы адресации

6502 имеет два режима косвенной адресации, которые разыменовываются через 16-битные адреса, хранящиеся на нулевой странице:

  • Индексированные косвенные, например LDA (10 долларов США, X), добавляет регистр X к заданному нулевому адресу страницы перед чтением 16-битного вектора. Например, если X равно 5, он считывает 16-битный адрес из ячейки $ 15 / $ 16. Это полезно, когда на нулевой странице есть массив указателей.
  • Косвенная индексация LDA (10 долларов США), Y добавляет регистр Y к 16-битному вектору, считанному с заданного нулевого адреса страницы. Например, если Y равно 5, а $ 10 / $ 11 содержит вектор $ 1000, это считывает значение из $ 1005. Это выполняет адресацию со смещением указателя.

Обратной стороной этой модели является то, что, если индексирование не требуется, один из индексных регистров все равно должен быть установлен в ноль и использоваться в одной из этих инструкций. В 65C02 добавлен режим неиндексированной косвенной адресации. LDA (10 долларов США) для всех инструкций, которые использовали индексированные косвенные и косвенные режимы индексации, освобождая индексные регистры.[11]

6502-е годы JMP инструкция имела уникальный (среди 6502 инструкций) режим адресации, известный как «абсолютная косвенная», при котором считывалось 16-битное значение из заданного адреса памяти, а затем осуществлялся переход к адресу в этом 16-битном значении. Например, если ячейка памяти $ A000 содержит 34 доллара, а $ A001 - 12 долларов, JMP (000 австралийских долларов) прочитает эти два байта, построит значение $ 1234, а затем перейдет в это место.

Одним из распространенных способов использования косвенной адресации является создание отраслевые столы, список точек входа для подпрограммы доступ к которому можно получить с помощью индекса. Например, драйвер устройства может перечислить точки входа для ОТКРЫТО, ЗАКРЫТЬ, ЧИТАТЬи т.д. в таблице по цене A000 $. ЧИТАТЬ - третья запись с нулевым индексом, и для каждого адреса требуется 16 бит, поэтому для вызова ЧИТАТЬ можно было бы использовать что-то похожее на JMP (A004 долл. США). Если драйвер обновлен и код подпрограммы перемещается в память, любой существующий код будет работать, пока таблица указателей остается на уровне $ A000.

В 65C02 добавлен новый режим «абсолютного косвенного индексирования», который упростил использование таблиц переходов. В этом режиме к абсолютному адресу добавляется значение регистра X, а из полученного местоположения берется 16-битный адрес. Например, чтобы получить доступ к ЧИТАТЬ функции из таблицы выше, можно сохранить 4 в X, тогда JMP (000 австралийских долларов, X). Этот стиль доступа упрощает доступ к таблицам переходов, поскольку один базовый адрес используется в сочетании с 8-битным смещением.[11]

Новые и измененные инструкции

Помимо новых режимов адресации, «базовая модель» 65C02 также добавила набор новых инструкций.[12]

  • INC и DEC без параметров теперь увеличивайте или уменьшайте аккумулятор. Это было странным упущением в исходном наборе инструкций, который включал только INX/DEX,INY/DEY и INC адрес/DEC адрес. Некоторые ассемблеры используют альтернативные формы В/ДЭА или же INC A/ДЕКАБРЬ А.[12]
  • СТЗ адрес, Хранить ноль в адрес. Заменяет необходимость LDA # 0; STA адрес и не требует изменения значения аккумулятора. Поскольку эта задача является общей для большинства программ, использование STZ может уменьшить размер кода, как за счет устранения LDA, так и любого кода, необходимого для сохранения значения аккумулятора, обычно PHA PLA пара.[13]
  • PHX,PLX,PHY,PLY, сдвигайте регистры X и Y в / из стека. Раньше только аккумулятор и регистр состояния имели инструкции push и pull. X и Y можно было сложить в стопку, только сначала переместив их в аккумулятор с помощью TXA или же ТЯ, тем самым изменяя содержимое аккумулятора, затем используя PHA.[14]
  • БЮСТГАЛЬТЕР, филиал всегда. Работает как JMP но использует 1-байтовый относительный адрес, как и другие ветви, с сохранением байта. Скорость часто такая же, как у 3-х тактного абсолютного JMP если страница не пересечена, что приведет к БЮСТГАЛЬТЕР версия на 1 цикл длиннее (4 цикла).[15] Поскольку адрес относительный, он также полезен при написании перемещаемого кода,[13] обычная задача в эпоху до блоки управления памятью.

Инструкции по работе с битами

И WDC, и Rockwell внесли улучшения в функции тестирования долот и манипуляции с ними в 65C02. WDC добавила новые режимы адресации к инструкции BIT, которая присутствовала в 6502, а также две новые инструкции для удобного управления битовыми полями, что является обычным действием в драйверах устройств.

BIT в 65C02 добавляет немедленный режим, нулевую страницу, проиндексированную X, и абсолютную проиндексированную X-адресацией.[12] Адресация в немедленном режиме особенно удобна тем, что является полностью неразрушающей. Например:

LDA <регистр>
БИТ №% 00010000

может использоваться вместо:

LDA <регистр>
И #% 00010000

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

В дополнение к усовершенствованиям инструкции BIT, WDC добавил две инструкции, предназначенные для удобного управления битовыми полями:

  • БСЭ адрес и TRB адрес, Тесть и Set Bэто и Тесть и рeset Bэто.
Маска в аккумуляторе (.A) логически объединяется с памятью в адрес, где может быть нулевая страница или абсолютное. Флаг Z в регистре состояния настраивается в соответствии с результатом логического И - никакие другие флаги регистра состояния не затрагиваются. Кроме того, биты в адрес устанавливаются (TSB) или очищаются (TRB) в соответствии с маской в .A. Вкратце, TSB выполняет логическое ИЛИ после логического И и сохраняет результат логического ИЛИ в адрес, тогда как TRB сохраняет результаты логического И в адрес. В обоих случаях флаг Z в регистре состояния указывает результат .A И адрес до содержания адрес изменено. Таким образом, TRB и TSB заменяют последовательность инструкций, по существу объединяя инструкцию BIT с дополнительными шагами для сохранения вычислительных изменений, но таким способом, который сообщает о состоянии затронутого значения до его изменения.[1]

Изменения Роквелла добавили больше инструкций по манипулированию битами для непосредственной установки и тестирования любого бита, а также объединения тестов, очистки и перехода в один код операции. Новые инструкции были доступны с самого начала в семействе Rockwell R65C00,[16] но не входил в исходную спецификацию 65C02 и не встречался в версиях, выпущенных WDC или другими лицензиатами. Позже они были скопированы обратно в базовый проект и были доступны в более поздних версиях WDC.

Особые инструкции Rockwell:

  • SMBкусочек# zp/Юанейкусочек# zp. Установить или сбросить (сбросить) номер бита кусочек# в нулевом байте страницы zp.
RMB и SMB используются для очистки (RMB) или установки (SMB) отдельных битов в битовом поле, каждая из которых заменяет последовательность из трех инструкций. Поскольку RMB и SMB предназначены только для адресации нулевой страницы, полезность этих инструкций ограничена, и они в первую очередь важны для систем, в которых регистры устройств представлены на нулевой странице. В кусочек# компонент инструкции часто записывается как часть мнемоники, например SMB1 12 долларов США который устанавливает бит 1 в адресе нулевой страницы $ 12. Некоторые монтажники относятся к кусочек# как часть операнда инструкции, например, SMB 1,$12, который имеет то преимущество, что позволяет заменять его именем переменной или вычисляемым числом.[13]
  • BBR кусочек#,компенсировать,адрес и BBS кусочек#,компенсировать,адрес, Переход при установке / сбросе бита.
Та же адресация нулевой страницы и ограничения, что и RMB и SMB, но переходят на адрес если выбранный бит очищен (BBR) или установлен (BBS). Как и в случае с RMB и SMB, BBR и BBS заменяют последовательность из трех инструкций.[13]

Режимы с низким энергопотреблением

В дополнение к новым командам, указанным выше, WDC также добавил STP и WAI инструкция по поддержке маломощных режимов.

STP, ОСТАНОВИТЕ процессор, остановил всю обработку до тех пор, пока не будет выполнен сброс оборудования. Это может быть использовано для перевода системы в «спящий» режим, а затем ее быстрого выхода из режима перезагрузки. Обычно для этого требовалась какая-то внешняя система для поддержки основной памяти, и она не использовалась широко.

WAIt имел аналогичный эффект, входя в режим пониженного энергопотребления, но эта инструкция снова разбудила процессор при получении прерывания. Ранее обработка прерывания обычно включала запуск цикла для проверки того, было ли получено прерывание, иногда известного как "прядение ", проверяя тип при получении, а затем переходя к коду обработки. Это означало, что процессор работал в течение всего процесса.

Напротив, в 65C02 код прерывания мог быть написан с помощью WAI сразу за которым следует JSR или же JMP обработчику. Когда WAI была обнаружена, обработка остановлена, и процессор перешел в режим пониженного энергопотребления. Когда прерывание было получено, оно немедленно обработало JSR и обработал запрос.

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

65SC02

65SC02 - вариант WDC 65C02 без битовые инструкции.[17]

Известные применения 65C02

Домашние компьютеры

Приставки для видеоигр

Другие продукты

Смотрите также

Примечания

  1. ^ Некоторые источники, включая предыдущие версии этой статьи, утверждают, что это 1978 год. Это была дата, когда Билл Менч, главный разработчик, основал WDC. Менч особо отмечает 1981 год, говоря о дизайне 1984 года.
  2. ^ В статье Вагнера от июня 1983 г. упоминается, что он доступен в течение «нескольких месяцев». Учитывая типичные задержки публикации на тот момент, это может быть датировано концом 1982 года.

Рекомендации

Цитаты

  1. ^ а б c d е ж грамм Вагнер 1983, п. 204.
  2. ^ Коэн, Филипп (2 марта 2018 г.). «Стек 6502» (PDF).
  3. ^ Тейлор и Уотфорд 1984, п. 174.
  4. ^ «6502 проекта ЦП на HDL (для FPGA)».
  5. ^ "Плата разработчика W65C02DB".
  6. ^ "W65C02S-14".
  7. ^ Паркер, Нил. «Набор команд 6502 / 65C02 / 65C816 декодирован». Страница Нила Паркера Apple II.
  8. ^ Варди, Адам (22 августа 1995). «Дополнительные инструкции ЦП серии 65XX».
  9. ^ Стейл, Майкл (28 сентября 2010 г.). "Измерение ошибки ROR в раннем MOS 6502".
  10. ^ а б «Различия между NMOS 6502 и CMOS 65c02». Получено 27 февраля 2018. Флаги N, V ​​и Z были неправильными после десятичной операции (но C был в порядке).
  11. ^ а б Кларк, Брюс. «Коды операций 65C02».
  12. ^ а б c Вагнер 1983, п. 200.
  13. ^ а б c d Вагнер 1983, п. 203.
  14. ^ Вагнер 1983 С. 200-201.
  15. ^ "W65C02S Лист данных" (PDF).
  16. ^ Вагнер 1983, п. 199.
  17. ^ Закс, Родней. Программирование 6502. п. 348.
  18. ^ http://archaicpixels.com/HuC6280

Библиография

  • Вагнер, Роберт (июнь 1983 г.). "Сборочные линии". Softtalk. С. 199–204.CS1 maint: ref = harv (связь)
  • Тейлор, Саймон; Уотфорд, Боб (июль 1984 г.). «6502 возрождение». Мир персональных компьютеров. С. 174–175.CS1 maint: ref = harv (связь)

дальнейшее чтение

  • 65C02 Лист данных; Центр западного дизайна; 32 страницы; 2018.
  • Программирование 65816 - в том числе 6502, 65C02, 65802; 1-е изд; Дэвид Айз и Рон Личти; Прентис Холл; 636 страниц; 1986; ISBN  978-0893037895. (архив)

внешняя ссылка