Как стать автором
Обновить

Комментарии 17

В порядке "стилистических" придирок: лучше избегать таких типов, как WORD, потому что их трактовка различается от платформы к платформе. На ПК исторически сложилось, что слово = 16 разрядов независимо от разрядности процессора, но, скажем, на 32-разрядных ARM слово -- таки 32 бита, ну а на том же 6502 слов на уровне терминологии вообще не было. Так что я предпочитаю, чтобы разрядность подобных типов прямо у них и указывалась (лично я использую всякие там int8/uint8 и т.д. и т.п.).

Насчёт "множества режимов адресации": восемь -- это много, лишь немногие архитектуры имели больше, ну а десятков действительно разных режимов, возможно, нигде никогда и не было. Нет, если считать за разные виды адресации один и тот же вид, но с разными регистрами, то можно и сотни насчитать -- но разными они таки не будут.

Ну и, наконец, эмуляция процессора -- это хорошо, но она приобретает смысл лишь в случае эмуляции целого компьютера -- и таких проектов весьма много. А без этого... Ну, сделали выполнение команд, и что дальше? Даже не поиграешь в какую-нибудь древнюю игрушку для Эпла-2, Денди или нашего Агата, которые как раз на 6502 были :)

ну а десятков действительно разных режимов, возможно, нигде никогда и не было.

если считать для всех видов инструкций и для всех типов памяти например в AVR архитектуре то больше десятка насчитать наверно можно, там для разных диапазонов памяти свои инструкции. Например к регистрам можно обращаться как к памяти по адресу а можно как к регистрам, в самих регистрах есть веделенный диапазон с которым могут работать только определенные инструкции, память IO регистров - это другой специальный тип памяти там тоже есть спец-режимы для разных областей, а еще есть память программ в которой тоже можно данные хранить и есть спец инструкции для их извлечения, еще есть еeprom память, память подключаемая по внешней шине... Это то что помню навскидку.

Десяток -- да, но не несколько десятков, думаю. В VAX-11, кажется, 12 было. В AVR8 -- да, примерно как Вы написали (точно уж не помню, писал под неё только один раз на асме, хоть и коммерческий проект был -- но 10+ лет назад, подробности, есно, давно выветрились).

А вот если говорить о памяти, подключаемой как внешнее устройство (скажем, EEPROM на I2C), то проц об этом ничего не знает и никаких особых видов адресации не имеет: там доступы выполняются к регистрам контроллера I2C или какая там шина используется.

Насколько я помню, у 6502 было 13 документированных режимов адресации. Правда, были среди них и такие, которые, например, использовались только одной командой. И, действительно, 13 и даже 8 – это много.

Другое дело, что конкретно мнемокод AND допускает 8 документированных режимов адресации.

В большинстве проектов эмуляторов, что я видел, декодер сделан на switch-case. Удивляет?

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

Switch/case это самое оптимальное решение, как раз потому, что код сложен в одном месте.

Уже догадались, какой стала вторая и последняя итерация? Таблица вызовов!

Компилятор превращает switch/case в таблицу автоматически.

Рекомендую ознакомиться с этим проектом (потактовый эмулятор 6502)

https://github.com/floooh/chips/blob/master/chips/m6502.h

Легко читать, легко понять.

построение на их основе полноценных систем

Тем более нужен потактовый эмулятор, потому что результат может меняться в зависимости от того, на каком такте команды вы запишете данные в регистр железки (или в память).

Кстати о потактовых эмуляторах: чисто для интереса делал эмулятор zx-spectrum и там пришлось делать эмулятор процессора z80 не потактовый, но поцикловый. Один машинный цикл - это несколько тактов, а одна команда процессора - несколько машинных циклов.

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

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

В любом случае, вешать останов эмулятора на какой-то код команды – плохое для практического использования решение, потому что ситуация, когда исполнение начинает гулять по случайным байтам – не редкость. Архитектура 6502 гарантирует, что мы остановимся при этом на первом BRK (вот только не помню, нет ли дополнительных недокументированных опкодов у BRK, помимо $00).

А его на уровне схемы не выкладывали, не знаете?

Насчёт оригинальной схемы не знаю, но схемотехника для ПЛИС вроде есть.

Спасибо :)

Отличный проект. Спасибо что поделились. На старых процессорах хорошо если: register, direct, indirect, indexed - есть вообще. На старом Intel встречал: можно 8 bit , а можно - 16 bit двумя регистрами.

А почему MOS6502_Status сделан байтами, а не битовыми полями? Как раз слово состояния процессора автоматически получилось.

Именно битовыми полями и сделан.

struct MOS6502_Status {  
    BYTE C  :1;             // Carry Flag  
    BYTE Z  :1;             // Zero Flag  
    BYTE I  :1;             // Interrupt Disable  
    BYTE D  :1;             // Decimal Mode  
    BYTE B  :1;             // Break Command  
    BYTE NU :1;             // Not Used  
    BYTE V  :1;             // Overflow Flag  
    BYTE N  :1;             // Negative Flag
}

Тут единичка после двоеточия означает, что переменной из всего BYTE отведен только один бит.

Нельзя не напомнить, об одном из первопроходцев эмуляторостроения Марате Файзулине, и его странице посвященной эмуляции разных систем. Так же на этой странице находится статья "Как написать эмулятор Компьютера"

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации