Это всё есть в оригинале от DEC, а не в попытках переделки
Вид для печати
Это всё есть в оригинале от DEC, а не в попытках переделки
Все проще. Диспетчер памяти к PDP-11 прикрутили слишком сбоку - почти без вмешательства в аппаратуру процессора, и, поэтому, у программы нет средств нормального манипулирования длинными адресами. Вспомните х86*16. У него есть команды дальнего перехода, дальнего вызова подпрограммы, дальней косвенной адресации... То есть, при помощи специальных команд ЦП доступно все адресное пространство, все данные для этого содержались в регистрах процессора, при переключении задач они входили в контекст сохранения/восстановления. А здесь до этого не догадались, ДП прикрутили сбоку, как внешнее устройство, систему команд оставили, практически, прежней, а ей доступно только 64К. То есть, конечно, можно сделать что-то подобное, используя ресурсы ОС, что в некотором роде и сделали. Но это, прежде всего, долго, "на лету" не сделаешь. То есть, допустим, не сделаешь последовательный вызов нескольких дальних подпрограмм из быстрого цикла, поскольку он перестанет быть быстрым - вызов ОС для переключения - это не одна машинная команда, как в х86. Пусть и не самая быстрая...
С другой стороны, такая модификация системы команд отправила бы лесом бОльшую часть наработанного до этого... ИМХО.
- - - Добавлено - - -
Да, умелое планирование оверлеев и правильное размещение данных позволяет решать многое, но это надо напрягаться программисту, тогда, как при наличии расширенной системы команд (как в х86, допустим) с этим справляются компиляторы.
Это если из системы, которая сама управляет MMU - типа XM монитора или RSX. Если прога сама будет управлять MMU - всё несколько быстрее и можно даже проимитировать дальние вызовы и возвраты, но ценой поддержки транслятором или программистом и всё равно это будет достаточно медленно.
И ещё надо учесть факт, что PDP создавались изначально даже не во времена "640 кб хватит всем", память была крайне дорогой, процессор то же не за фантики можно было купить, плюс конкуренция по цене (с той же IBM), поэтому делали не "машину мечты", а то, что будет неплохим и хорошо продающимся. Ну и если вдруг памяти мало, а буратино попался богатым, можно было взять проц (корзина с платами), воткнуть в него (в корзину) ещё плату, (возможно) переставить перемычки и вуаля - у нас уже 248 кб (а то и 4 мб) памяти. А не нужно было столько памяти или буратино просадил все свои сольдо - продаём базовый процессор подешевле, ну а если вдруг сольдо таки найдутся - продаём доп плату и все. Так что не фига он там не был прикручен
- всё было очень логично - с точки зрения ведения бизнеса, а не хотелок людей из 21 века
И точно так же сделали FPP
И кстати - это сейчас, когда всё упаковано в одну две микросхемы похожее решение (вот одна микросхема без MMU, а вот вторая микросхема - MMU) было бы решением сбоку, а во времена процессоров из нескольких плат - всё достаточно логично и с точки зрения техники
Необязательно. Виртуальные массивы в FORTRAN при работе под SJ/FB - тому пример. И работать, кстати, будут быстрее, чем под ОС, потому что той ещё надо управлять - кто где память занял
Слепить при условии разделения кода по нескольким файлам можно и без программиста - на коленках, но выжать максимум производительности, а не так, что бы постоянно оверлеи с диска подкачивались (в памяти переотображались) - тут таки да, придётся попотеть программисту
А цену работа под включённым MMU можно понять (весьма грубо, правда) по
Под SB
Копирование в NL:
65534*512/(2:37)/1024 = ~ 209 кб/с
Копирование на другой ZF с проверкой (два чтения, одна запись, сравнение в памяти)
65534*512*3/(11:25)/1024 = ~ 144 кб/с
Под XM
Копирование в NL:
65534*512/(3:07)/1024 = ~ 175 кб/с
Копирование на другой ZF с проверкой (два чтения, одна запись, сравнение в памяти)
65534*512*3/(13:13)/1024 = ~ 124 кб/с
то есть в районе 10-20 процентов
- - - Добавлено - - -
Аха, конечно, там одни тупые пьяные инженеры сидели
Это не столько цена самогО MMU, сколько цена более навороченной ОС, в том числе, конечно, и затраты на обслуживание MMU, но не только.
ИМХО, ни фига! Проц без ДП не переделывался влёгкую в проц с ДП, это совершенно разные изделия.
Тем не менее, оно, все-таки, сбоку - добавили несколько битов в PSW, добавили второй указатель стека со схемой выбора, кому из них работать, прицепили ДП, как внешнее устройство, завернули шину адреса через него, и все. Ах, да, еще подправили дешифратор команд, запретить исполнение некоторых команд в юзермоде.
Злой ты! :) Тем не менее, мэйнстрим DEC'и проглядели, как и Межделмаш. Хотя, конечно, в то время, когда к PDP-11 цепляли ДП, будущее еще было туманным...
DEC-11-HKBB-D
KB11-A Central Processor unit maintenance manual
Страница 1-4
The KT11-C Memory Management Unit is an OPTION that replaces the SJB System Jumper Board to provide both forms of memory management
Ну и менее надёжный источник - моя память. Когда на химфак МГУ привезли СМ-4 и наш электронщик её приводил в рабочее состояние, насколько мне не изменяет память, он вначале её приводил в чувство БЕЗ ДП, гоняя тесты сначала с перфолент, а потом, когда оживил более менее - грузил с RK05 - сообщение 28KW достаточно хорошо помню. И только после этого он начал смотреть на ДП
- - - Добавлено - - -
О, читаем 1-4 в конце:
1.1.4 Expanded Systems
The elements that distinguish a PDP-11/45 System have all been introduced in the three preceding paragraphs.
These elements are the following:
a. the KB11-A Central Processor Unit
b. the MS11 Semiconductor Memory System
c. the FP11 Floating-Point Processor
d. the KT11-C Memory Management Unit
All PDP-11/45 Systems include the KB11-A; however, ALL OTHER COMPONENTS are OPTIONAL
На СМ-4 - было давно, поэтому не гарантирую, только подсказывает память, на 1420 максимум что делали - вырубали один раз кэш-память проца, когда чинили, на 1600 тоже не было случая выключения ДП, хотя с 1600-ой я по первости сел в лужу - зуб давал, что 248 Кб, а оказался мег
Ну и 11/45 (насколько мне не изменяет память, но искать лень) - мог работать как с 18-битным MMU, так и с 22-ух битным
The game is very similar to the traditional Star-Trek game with the following exceptions.
First, the game involves several players (1-6), each of whom has his own terminal and starship.
Second, the game runs in real time as far as the players are concerned. For example, if you are going warp 8 you will continue to move regardless of your activity at the terminal (unless you are destroyed, hit something, run out of energy, or change your warp speed). Each player's status and position as well as the scores of all players is displayed and continuously updated at each player's terminal. (The update rate is twice per second, but the source code is commented on where to change it should you wish to do so.)
Third, at the present time there are no Klingons or Romulans to shoot down, instead you shoot (or at least attempt to shoot) the other players.
Игра очень похожа на традиционную игру СтарТрек со следующими отличиями.
Во-первых, в игре участвуют несколько игроков (от 1 до 6), играющими каждый со своего термаинала и на своем звёздном судне.
Во-вторых, игра идёт настолько в реальном времени, насколько игроки заинтересованы. Например, если Вы начали перемещаться варпом со скоростью 8, движение продолжается независимо от ваших действий за терминалом (если только Вы не уничтожены, не ударились обо что-то, не израсходовали всю энергию или не изменили скорость варпа). Статус и позиция каждого игрока, а так же счёт всех игроков отображается и постоянно обновляется на терминале каждого игрока (по умолчанию частота обновления - дважды в секунду, но в исходном тексте есть комментарии - как это изменить, будь на то ваша воля).
В-третьих, в настоящее время во Вселенной нет ни клингонов, ни ромулан, которых можно было бы перестрелять, зато Вы можете перестрелять (ну или по крайне мере попробовать перестрелять) других игроков.
...
4.0 TERMINATING THE GAME
It is important that the last MTREK players clean up the system before they leave. This is done by issuing the following set of commands:
1. Terminate each PLAYER program by entering the "Q" command.
2. If the universe manager MTREKD does not terminate automatically abort it as follows:
<CNTRL> C
MCR> ABORT
3. If you are running any ROBOT programs abort each one as follows:
<CNTRL> C
MCR> ABORT
Now mop up the blood, sweat, and tears; logout; and go home.
4.0 Завершение игры
Важно, что бы последние игроки MTREK убрались за собой в системе перед тем, как выйти.
Это делается следующими действиями:
1. Завершить работу каждой программы PLAYER вводом команды Q.
2. Если программа MTREKD, управляющая вселенной, не завершила свою работы автоматически, завершите её работу следующими действиями:
Ctrl/C
MCR> ABORT
3. Если Вы запустили одну или несколько копий программы ROBOT, завершите их работу следующими действиями:
Ctrl/C
MCR> ABORT
А теперь время вытереть кровь, пот и слезы, выйти из системы и идти домой.
-------------------
Другая игрушка:
This game is similar to the arcade game, CENTIPEDE. As written, it must be played on a VT100 video terminal. You have a gun, which you can move around on the bottom third of the screen (player's zone) and with which you can shoot at various invading creatures. Bullets from your gun travel upwards until they either hit a target or the top of the screen. No more than one bullet can be on the screen at a time. Centipedes appear at various times on the screen, consisting of a head and from zero to eleven body segments. Centipedes move back and forth across the screen, descending a level when they hit a screen boundary, a mushroom, or another centipede. When they reach the bottom of the screen they begin to ascend in the same manner, but remain within the player's zone. The object of the game is to kill these centipedes before they eat your gun.
Модуль из неё, написан на RATFOR:
Код:SUBROUTINE BULCOL
#
# THIS SUBROUTINE CONTROLS COLLISIONS BETWEEN BULLETS AND TARGETS.
#
IMPLICIT INTEGER (A-Z)
INCLUDE SY:CNTPED.CMN
INCLUDE SY:UVT100.DAT
BYTE THREE,SIX,NINE
% DATA THREE,SIX,NINE / "063,"066,"071 /
#
# CHECK IF CURRENT BULLET LOCATION COLLIDES WITH MUSHROOM
#
IF (MSHBRD(BULX,BULY) > 0) [
BULACT = 0
MSHBRD(BULX,BULY) = MSHBRD(BULX,BULY) - 1
IF (MSHBRD(BULX,BULY) == 0) [
PSNBRD(BULX,BULY) = 0
SCORE = SCORE + 1
]
]
#
# CHECK IF CURRENT BULLET LOCATION COLLIDES WITH CENTIPEDE(S)
#
DO I = 1,MAXCNT [ #LOOP THROUGH CENTIPEDE TABLE ENTRIES
IF (CLEN(I) == 0)
NEXT #UNUSED ENTRY
DO J = 1,CLEN(I) [ #LOOP THROUGH LINKS FOR THIS ENTRY
IF (BULX == CX(I,J) .AND. BULY == CY(I,J)) [ #COLLISION
BULACT = 0
MSHBRD(BULX,BULY) = 4 #CREATE MUSHROOM IN MUSHROOM TABLE
CNTBRD(BULX,BULY) = 0 #CLEAR CENTIPEDE BOARD AT THIS LOC
IF (J == 1) [ #COLLISION WITH CENTIPEDE HEAD
SCORE = SCORE + 100 #INCREMENT SCORE
CLEN(I) = CLEN(I) - 1 #'SHORTEN' CENTIPEDE
IF (CLEN(I) > 0) [ #IF LENGTH NOT ZERO
DO K = 1,CLEN(I) [ #UPDATE LINKS IN CENTIPEDE TABLE
CX(I,K) = CX(I,K+1)
CY(I,K) = CY(I,K+1)
]
CALL UVT100(CUP,CX(I,1),CY(I,1)) #DISPLAY NEW CENTIPEDE HEAD
IF (CDIR(I) == LEFT)
CALL GETADR(PRL,CLHEAD)
ELSE IF (CDIR(I) == RIGHT)
CALL GETADR(PRL,CRHEAD)
ELSE
CALL GETADR(PRL,CDHEAD)
CALL WTQIO(IOWVB,5,2,,,PRL)
]
]
ELSE [ #COLLISION WITH CENTIPEDE BODY
SCORE = SCORE + 10 #INCREMENT SCORE
NEWLEN = CLEN(I) - J
CLEN(I) = J - 1
IF (NEWLEN > 0) [
DO K = 1,MAXCNT [ #FIND EMPTY SLOT IN CENTIPEDE TABLE
IF (CLEN(K) > 0)
NEXT
DO L = 1,NEWLEN [ #MOVE NEW CENTIPEDE LINKS TO THIS SLOT
CX(K,L) = CX(I,L+J)
CY(K,L) = CY(I,L+J)
]
CLEN(K) = NEWLEN #NEW CENTIPEDE LENGTH
CDIR(K) = CDIR(I) #NEW CENTIPEDE DIRECTION OF MOTION
CRISE(K) = CRISE(I) #NEW CENTIPEDE ASCEND OR DESCEND
CBOT(K) = CBOT(I) #NEW CENTIPEDE HIT BOTTOM FLAG
CALL UVT100(CUP,CX(K,1),CY(K,1))
IF (CDIR(K) == LEFT) #DISPLAY NEW CENTIPEDE HEAD
CALL GETADR(PRL,CLHEAD)
ELSE IF (CDIR(K) == RIGHT)
CALL GETADR(PRL,CRHEAD)
ELSE
CALL GETADR(PRL,CDHEAD)
CALL WTQIO(IOWVB,5,2,,,PRL)
BREAK
]
]
]
]
]
]
#
# CHECK IF CURRENT BULLET LOCATION COLLIDES WITH SPIDER
#
IF (SPIACT == 1 .AND. BULX == SPIX .AND. BULY == SPIY) [
BULACT = 0
SPIACT = 0
SPITIM = TIMER + 30 #SCHEDULE NEXT SPIDER
ITMP = GUNX - SPIX
IF (ITMP < 0)
ITMP = 0
CALL UVT100(CUP,BULX,BULY)
IF (ITMP < 2) [ #INCREMENT SCORE
SCORE = SCORE + 900
CALL GETADR(PRL,NINE)
]
ELSE IF (ITMP < 4) [
SCORE = SCORE + 600
CALL GETADR(PRL,SIX)
]
ELSE [
SCORE = SCORE + 300
CALL GETADR(PRL,THREE)
]
CALL WTQIO(IOWVB,5,2,,,PRL) #DISPLAY POINTS FOR KILL
CALL WAIT(200,1) #WAIT 200 MILLISECONDS
]
#
# CHECK IF CURRENT BULLET LOCATION COLLIDES WITH FLEA
#
IF (FLEACT == 1 .AND. FLEX == BULX .AND. FLEY == BULY) [
BULACT = 0
FLEACT = 0
ICOUNT = 0
DO I = GMAR,BMAR [ #NEXT SCHEDULED FLEA TIME DEPENDS
DO J = LMAR,RMAR [ #ON NUMBER OF MUSHROOMS IN PLAYER ZONE
IF (MSHBRD(I,J) > 0)
ICOUNT = ICOUNT + 1
]
]
IF (ICOUNT < 5) #SCHEDULE NEXT FLEA
FLETIM = FLETIM + 20
ELSE
FLETIM = FLETIM + 200
SCORE = SCORE + 200 #INCREMENT SCORE
]
#
# CHECK IF CURRENT BULLET LOCATION COLLIDES WITH SCORPION
#
IF (SCOACT == 1 .AND. SCOX == BULX .AND. SCOY == BULY) [
BULACT = 0
SCOACT = 0
SCOTIM = SCOTIM + 200 #SCHEDULE NEXT SCORPION
SCORE = SCORE + 1000 #INCREMENT SCORE
]
#
# IF BULLET HIT SOMETHING, DISPLAY APPROPRIATE CHARACTER
#
IF (BULACT == 0) [
CALL UVT100(CUP,BULX,BULY)
CALL GETADR(PRL,SPACE)
IF (MSHBRD(BULX,BULY) > 0)
CALL GETADR(PRL,MSHCHR)
IF (PSNBRD(BULX,BULY) == 1)
CALL GETADR(PRL,PSNCHR)
CALL WTQIO(IOWVB,5,2,,,PRL)
]
RETURN
END