Флейм
GameDev.ru / Флейм / Форум / CISC-x80: ПРАвәльный 8-битный «ДОМАШНИЙ» (псевдо-совместимый с PC-XT / CP/M-80 / DOS)

CISC-x80: ПРАвәльный 8-битный «ДОМАШНИЙ» (псевдо-совместимый с PC-XT / CP/M-80 / DOS)

Advanced: Тема повышенной сложности или важная.
Страницы: 1 2 314 15 Следующая »
AlikberovПостоялецwww22 мая 201812:56#0
Совместимость
На уровне ассемблера процессор наиболее совместим с i8086, что позволяет использовать любой из популярных отладчиков при написании ПО.
На уровне машинного кода в относительном плане процессор на 60% совместим с i8080, но не обеспечивает обратную поддержку в чистом виде и не поддерживается существующими трансляторами.
(Автором, однако, разработан ассемблер, включённый в состав эмулятора.
К сожалению, наблюдались ошибки с вычислением относительных адресов ветвлений, так как в процессоре команды перехода могут записываться двумя и тремя байтами, однозначно нелегко определить длину самой операции перехода, что влияет и на адресацию всех последующих меток. Это было довольно неприятным сюрпризом при разработке даже небольших программ.
)

Архитектура
Процессор задуман изначально на выполнение до 128 процессов вытесняющим порядком.
Из этого числа выделяется до 99 прикладных задач и 28 сервисных/диспетчерских.
Для разделения оперативных данных между процессами имеется контекстный файл объёмом до 256 байт с хранением состояния всех РОН и указателей, а также раскладки секций пространства памяти.

Файл контекста
Архитектурой данного процессора предусматривается исполнение нескольких задач в вытесняющем цикле на аппаратном уровне.
Для этой задачи предназначен «контекстный модуль» объёмом до 128 страниц по 256 байт каждая.
Всего предусматривается возможность исполнения до 99 прикладных задач (страницы 1…99), 28 сервисных задач (страницы 100…127) и одной системной (страница #0)…
Каждая страница разбита на несколько зон:
«00…9F» - ячейки хранения комплексных инструкций;
«A0…DF» - ячейки хранения значений РОН;
«F0…FF» - ячейки указателей инструкций основного кода и сервисного.
При этом, все ячейки также линейно пересекаются служебными ячейками специального назначения.

+ Модуль контекста
+ Файл контекста
+ Эмуляция
+ Особенности системы команд

Правка: 4 июня 2018 9:17

AlikberovПостоялецwww22 мая 201812:56#1
«RESET»: Сброс процессора
Внешний вывод процессора для обеспечения аппаратного «СБРОСа» архитектурно выполнен нетрадиционно и комплексно.
(Учитывая то, что производство логических микросхем с бОльшим числом (16 вместо 14) выводов в своё время имело свои технологические особенности конвеера и цену, непозволительной роскошью считаю делать процессору вывод, который практически всегда будет тупо принимать один уровень сигнала на протяжении непрерывной работы системы…)
Сигнал «СБРОС/RESET» процессора переименован в «RES/IN» (не путать с «RES IN»/«RESIN»/«RESET IN»…) и по-совместительству логически работает как сигнал «NMI» немаскируемого прерывания.
Во время прихода сигнала «RES/IN» вся прикладная часть программного кода прерывается и не может исполняться в принципе, так как управление всегда будет передаваться системному процессу. В этом случае данный сигнал подобен «ПАУЗЕ» всего прикладного кода…
Так как период выполнения системного кода никак аппаратно не ограничивается, регистры счётчика, предназначенные для ограничения периода исполнения прикладного кода, с приходом «RES/IN» включаются и декрементально отсчитывают такты периода выполнения системного кода. Если код системы «не справится» с ситуацией и не будет препятствовать обратному отсчёту, со стороны «RES/IN»-узла считается, что процессор неуправляем и производится его инициализация:
Регистр «IP» принимает значение «0xFF00», во все остальные РОН загружается фирменный идентификационный индекс (подобие «CPUID» у x86). Так как процессор имеет контекстную организацию и все РОН хранят собственную историю «LIFO-магазина», системный код «BIOS» может прочитать весь «CPUID-индекс». Надо сказать, что почти во все 256 байт контекста при инициализации просто загружается уникальный масочный «орнамент» производителя…
Сам системный код может отслеживать периоды «RES/IN» посредством тех счётчиков в периоде собственного исполнения, чтобы контроллировать периферийную ситуацию или принимать «ШИМ»-пакеты каких-нибудь экстренных данных…

«Режим ПДП»: Захват шины
Концептуально данный процессор не имеет никаких средств перевода своих выводов в состояние высокого импеданса.
Во-первых, это также сэкономило пару-другую выводов.
Во-вторых, учитывая то, что процессор сам по-себе - устройство деликатное, не силовое, нагрузочная способность его шин принципиально довольно низкая, чтобы разработчик вычислительной системы принудительно уделял внимание развязкам с мультиплексированием адресов между другими устройствами (как ПДП).
В-третьих, сам процессор может работать в режиме «устройства ПДП» посредством «сервисного контекста».
Именно потому процессор поддерживает как минимум три внутренних контекстных фрейма (3 x 256 байт статических регистров): Системный, Сервисный и Прикладной…

«Микрокод» или «Макрокод»?
Нижние 160 ячеек контекста задачи отвечают за хранение и исполнение своеобразного «микрокода» - область супер-оперативного исполнения дешифратором команд.
Ячейки могут хранить до 10 микропрограмм по 7 инструкций каждая. Длительность исполнения кода не превышает 1 такта на операцию при условии, что не происходит обращения к оперативной памяти.
В «режиме ПДП» процессор в каждом «WAIT»-цикле выполняет нужную «INT n»-инструкцию для запуска выбранного «микрокода» на исполнение. Так как внутри «микрокода» принципиально воспрещенны операции ветвления, там они играют особую исключительную роль для организации быстрого информационного потока между периферией…
Так как длительность префикса «WAIT» ограничивается 8-битным регистром-счётчиком, то периодически линейный пакет «ПДП»-периода не может быть шире 255 байт за квант времени…
Тем самым, в принципе, можно обойтись и без специализированной микросхемы ПДП, если качество производительности «ПДП-режима» вполне удовлетворительно. В таком случае, отпадает необходимость в программировании портов ПДП, а сам поток данных может иметь нелинейный характер адресации…
(В эмуляторе «скроллинг» экрана происходит как раз через «WAIT INT n»-цикл с адресацией по столбцам…)

Математические операции
Операций умножения/деления в АЛУ как бы нет. Но, безусловным циклом «LOOP n ADD r1,r2» можно достичь макроса «MUL r1,n», а условным циклом «WAIT cn SUB r1,r2» можно организовать макрос деления с прерыванием по «CF». Причём, регистры могут быть как 8-битными («AL» или другой), так и 16-битным «BX»…
Аппаратно это в перспективе позволило бы перехватить сами комбинации «LOOP+ADD»/«WAIT+SUB» и обработать их как следует самим внешним арифметическим устройством…

продолжение следует…

Правка: 3 июня 2018 15:50

AlikberovПостоялецwww22 мая 201812:56#2
Режимы «LOOP»/«WAIT»/«SKIP»
В подавляющем большинстве процессоров ход исполнения кода программ определяется изменением битов регистра флагов состояния АЛУ. Принцип выстановления флагов довольно прост и элементарен, но общее число всех доступных комбинаций при этом несколько меньше, чем битов самых флагов, так как существуют «логически невозможные комбинации»…
В «x80» такие комбинации возможны и используются…
Комбинация флаговРежим и управляющая инструкция
SF+ZFSKIP - холостое исполнение нескольких последующих инструкций
PF+ZFLOOP - безусловное исполнение одной инструкции несколько раз / особенное исполнение нескольких следующих инструкций
SF+PF+ZF(+CF)WAIT - условное исполнение одной инструкции несколько раз и пока CF установлен

Тем самым, при считывании флагового регистра из стека инструкцией «POP AF» процессор может оказаться в режиме «SKIP»/«LOOP»/«WAIT». То есть, переключать режимы можно как «PUSH/POP» трюками, так и специальными соответствующими инструкциями.
При этом, изменение флагов «SF»/«PF»/«ZF» на время активности «LOOP»/«WAIT»-режимов блокируется, только «CF»-флаг изменяется «сквозным» способом…
LOOP + AND  --> AND with << ; Логическая операция со сдвигом второго аргумента
LOOP + CALL --> CALL + SKIP ; Вызов подпрограммы с пропуском n-инструкций
LOOP + CMC  --> 
LOOP + CMP  --> 
LOOP + HLT  --> 
LOOP + INT  --> INT  + SKIP ; Вызов API с пропуском n-инструкций
LOOP + JMP  --> JMP  + SKIP ; Переход с пропуском n-инструкций
LOOP + LOOP --> 
LOOP + MOV  --> MOV indexed ; Передача значений с расширенной индексацией
LOOP + NOP  --> LOOP + NOP  ; Удлинённая холостая операция
LOOP + NOT  --> 
LOOP + OR   --> OR with <<  ; Логическая операция со сдвигом второго аргумента
LOOP + POP  --> 
LOOP + PUSH --> 
LOOP + SKIP --> 
LOOP + RET  --> RET  + SKIP ; Возврат с пропуском n-инструкций
LOOP + WAIT --> 
LOOP + XCHG --> XCHG deeply ; Обмен значениями с глубоким доступом
LOOP + XOR  --> XOR with << ; Логическая операция со сдвигом второго аргумента

WAIT + AND  --> 
WAIT + CALL --> System Call ; Вызов системного API
WAIT + CMC  --> 
WAIT + CMP  --> 
WAIT + HLT  -->             ; Передача управления системе
WAIT + INT  --> Internal Run; Вызов заготовленного внутреннего макроса
WAIT + JMP  --> Interruption; Принудительная обработка прерывания с передачей управления на метку при наличии
WAIT + LOOP --> 
WAIT + MOV  --> MOV waitable; Доступ к ячейкам памяти как к портам ввода/вывода
WAIT + NOP  --> 
WAIT + NOT  --> 
WAIT + OR   --> 
WAIT + POP  --> waitable    ; Доступ к стеку как к порту для ввода слова
WAIT + PUSH --> waitable    ; Доступ к стеку как к порту для вывода слова
WAIT + SKIP --> 
WAIT + RET  --> 
WAIT + WAIT --> 
WAIT + XCHG --> 
WAIT + XOR  --> 
Ассемблером «x80» зарезервированно использование компактных макрос-циклов:
; Машинный код      ; Длинное
55 EC .. .. ..      |LOOP    CL      ; Начало безусловного цикла с счётчиком CL
.. 7A               |ADD     AL,DL   ; Сложением в цикле достигается умножение
; Машинный код      ; Короткое
55 EC 7A            |ADD!CL  AL,DL   ; Короткая запись мнемоники

; Машинный код      ; Длинное
55 00 E8 FE ..      |WAIT    CL      ; Начало условного цикла с счётчиком CL
.. 7B               |SUB     AL,DL   ; Вычитанием в цикле достигается деление
; Машинный код      ; Короткое
55 00 E8 FE 7B      |SUB?CL  AL,DL   ; Краткая форма записи

; Машинный код      ; Длинное
55 00 E8 FE ..      |WAIT    CL      ; Начало условного цикла пока если CF чист
77 A4 00            |MOV     AL,[DX] ; Чтение из памяти с ожиданием (режим порта ввода/вывода)
; Машинный код      ; Короткое
55 00 E8 FE 77 A4 00|MOV?CL  AL,[DX] ; Краткая форма
; Машинный код      ; Специальное
55 00 E8 FE 77 A4 00|IN      AL,DX,CL; Особая форма записи

Правка: 22 июня 2018 23:26

AlikberovПостоялецwww22 мая 201812:56#3
+ Почeму «Ы»?

Облачныe технологии рулят!
Verilog-модель процессора - все эти дни перенаписал десятки килобайтов вариантов.
Работает только инструкция «B8 EA|JMP 0» - тайм №3150…

Вы представить не можете, чего мне это стоило! Даже во сне отлаживал в каком-то гибридном редакторе, где сразу кучу проводков видно в окошке при изменении листинга…
Работает пока лишь одна эта «JMP», так как тупо корректирует шину адреса… То есть, никаких «IP»/«SP» и прочего - нет!
Сначала использовался тот самый «контекст», но он меня запарил… В итоге выкинул всё, так как надо было добиться адеквата в считывании самих инструкций. В итоге, на «NOP» уходит действительно 4 такта, так как я убедился, что в i8080/Z80 это правда…

К тому же, научился использовать «задачи» и «функции», но пока лишь для дизассемблинга мнемоник для выдачи в консоль…
Напоролся на проблему с использованием «=» и «<=», немножко поняв, как они работают…

P.S.: Как понимаете, дешифратор команд понимает лишь «JMP» (строка 346)

15'BXXX__1_XXX__1011_1000:/*--B8 --|JMP $+IB*/  Address += {{9{ID[7]}}, ID[6:0]};
Да и целый такт простоя уходит (оказывается) при сбросе регистра машинных циклов. Что-то я неправильно «завершаю инструкции»…

Правка: 20 июня 2018 16:22

0iStalkerМодераторwww22 мая 201813:06#4
Alikberov
> Или вот порядок следования регистров i8086 именно таков: AL, CL, DL, BL или AX,
> CX, DX, BX.

Нет тут никакого порядка, там всё чётко по функционалу 

AX - Accumulator
CX - Counter
DX - Data
BX - Base
SI - Source Index
DI  - Destination Index
SP - Stack Pointer
BP - Base Pointer
IP - Instruction Pointer
F - Flag Register

AlikberovПостоялецwww22 мая 201813:13#5
0iStalker
> Нет тут никакого порядка, там всё чётко по функционалу 
Знaю я это. Ни один справочник отца до дыр затёр, изучая разные процессоры.
Однако, даже функционально это никак не оправдывает: Умножение использует пары «AX» и «DX», то есть индексы 0 и 2, хотя могли бы иметь 0 и 1 (если «AX DX CX BX» предложили бы)…
Так что, в любом случае - косяк инженеров!

P.S.: Но тема же про другое…

=A=L=X=Постоялецwww22 мая 201813:21#6
AlikberovПостоялецwww22 мая 201813:43#7
=A=L=X= Смoтрю, оказывается я единственный, кто смог свою задумку набросать в рабочий эмулятор, состряпать ассемблер, да ещё написать какой-никакой BIOS.
(Какой я скромняжка)
MisanthropeПостоялецwww22 мая 201813:45#8
ты крут!
я вообще не понимаю что это такое, и нахрена это нужно.
AlikberovПостоялецwww22 мая 201813:49#9
Misanthrope
> я вообще не понимаю что это такое, и нахрена это нужно.
Вoт построю собственное государство на острове, разверну там ПВО с интернетом и серверами на x80, чтобы ни у кого не было нормального кода взломать меня.

Вот тогда я был бы крутым.:))

=A=L=X=Постоялецwww22 мая 201813:52#10
Alikberov
> кто смог свою задумку набросать в рабочий эмулятор,

Ну да, я же там на третьей странице разочаровался в однобайтовых опкодах и потерял к однобайтовым архитектурам интерес.
Как нибудь придумаю двухбайтовую.

Правка: 22 мая 2018 13:52

return [](){};Участникwww22 мая 201813:57#11
m68k дизайнился так чтобы на нем в т.ч. было удобно писать асм руками, но в 21 веке это тупиковый путь.
Сейчас надо дизайнить чтобы эффективнее декодировалось и исполнялось процессором.
Или чтобы было проще оптимизирующим компиляторам.
Или, например, чтобы производители могли увеличивать ширину симда, а программы могли его использовать без перекомпиляции (проект forwardcom)
AlikberovПостоялецwww22 мая 201814:02#12
return [](){};
> а программы могли его использовать без перекомпиляции
Нe читали?

=A=L=X=
> Как нибудь придумаю двухбайтовую.
Эмулятор с играми будет?
Нет, я серъёзно! В соседнeй теме про ZX вы тихо намекали, что 8-битки - не моё. И, мол, не нравится эмуляторы - пиши свой!

Теперь всё стало на свои места? ;-)

P.S.: Версия на github устаревшая, так как у меня на диске есть пробы с Тетрисом и двумя задачами…
Но там глючила переключалка контекстов временами и я запарился ковырять свои баги. Проект временно заморозился вообще!

Правка: 22 мая 2018 14:04

=A=L=X=Постоялецwww22 мая 201814:03#13
return [](){};
> но в 21 веке это тупиковый путь

Ну не то чтобы прямо уж совсем, но акцент с этого действительно исчезает.
Взять RISC - а ведь они как раз легки с точки зрения вбития машкодов прямо в память программ, потому что небольшое число этих самых опкодов и они круто ортогональны.
Однако, как показал опыт ARM, с современными декодерами можно наплевать и на это и экономить на нарушении ортогональности кода за счёт его компактификации в Thumb.
CISC и RISC почерпнув черты каждого слились на разных этапах - простота декодера стала неважна на общей сложности схем, зато ядро внутри работает даже не как RISC, а уже как VLIW, потому что варится в собственной ванночке конвеера.
Поэтому в целом современным архитектурам уже особо помогать не надо - тут уже любую дрянь можно нивелировать нарастающей сложностью чипов.
А вот подумать в разрезе "а что если бы 8-битный проц был..." - это про сабж.

=A=L=X=Постоялецwww22 мая 201814:03#14
Alikberov
> В соседнeй теме про ZX вы тихо намекали, что 8-битки - не моё.

Я? Где?

Страницы: 1 2 314 15 Следующая »

/ Форум / Флейм / ПроЭкты

2001—2018 © GameDev.ru — Разработка игр