Using resload_Protect#?

### Использование функции resload_Protect *?

#### Теория

Есть различные ситуации, при которых было бы очень полезно получать информацию о том, что установленная программа обращается к определенным участкам памяти. С помощью функции resload_Protect *? можно защищать участки памяти от чтения и/или записи процессором. Защита подразумевает, что каждый доступ к такой защищенной области инициирует исключительное событие "Ошибка Доступа", которое создаст соответствующее окно с сообщением от WHDLoad. Если вы объявляете область памяти защищенной, используя функцию resload_Protect *?, то WHDLoad изменит затронутые дескрипторы страниц в списке перевода диспетчера памяти (MMU). Теперь при каждом доступе к защищенной странице центральный процессор будет инициировать исключительное событие "Ошибка Доступа". Обработчик исключительных событий внутри WHDLoad проверит его причину. Если причиной был доступ к защищенной странице, но доступ не тронул защищенную область, то этот доступ будет эмулироваться, и продолжится нормальное выполнение программы. Иначе WHDLoad закончит работу и выдаст соответствующее окно с сообщением. Если происходит доступ к инструкции (т.е. центральный процессор пытается загрузить код), то это всегда будет эмулироваться, или иначе говоря, функция resload_Protect *? затрагивает только чтение и запись данных. Факт тот, что каждый доступ к защищенной странице (в настоящее время размер страницы равен $1000), создаст ошибку доступа, даже если защищенная область имеет длину всего 1 байт, в результате скорость выполнения программы очень сильно упадёт. Особенно, если части кода расположены на одной и той же странице. Если программа зависит от скорости выполнения, то возможна разница в выполнении. Таким образом, возможен вариант, что некоторые программы не будут работать с защищенной памятью.

#### Пример: контрольные суммы по коду

Если вы устанавливаете игру, используя WHDLoad, вы должны исправить в игре процедуры оригинальных загрузчиков таким образом, чтобы они использовали WHDLoad, для загрузки данных игры. Некоторые игры выполняют подсчет контрольных сумм в некоторых областях кода, чтобы определить, не изменялся ли оригинальный код. Эти подпрограммы проверки иногда очень трудно найти. Но использование функции resload_Protect *? в WHDLoad делает этот процесс очень легким. Все, что вы должны сделать, это защитить от чтения те байты, которые вы изменили в коде игры. Теперь каждая подпрограмма, которая попробует подсчитать контрольную сумму и прочитать ваш исправленный код, создаст ошибку доступа. И вы узнаете где расположена эта подпрограмма.

#### Ограничения

Вы не в коем случае не должны защищать участок памяти, куда указывает SSP. Если вы всё же это сделали, то произойдет Исключение, что приведёт к двойной ошибке шины (Double Bus Fault), потому что центральный процессор не сможет записать stackframe исключения. После двойной ошибки шины должна быть произведена перезагрузка для продолжения работы. WHDLoad проверяет конфликт защищенной области с SSP и заканчивает устраняет его, но это не помогает, если SSP изменяется позже.

- 68020 + 68851
  - эта конфигурация в данный момент не поддерживается
- 68030
  - 3-байтовые передачи не поддерживаются и создают Ошибку Доступа, такие передачи будут возникать, если произойдёт обращение к "длинному слову" на нечетном адресе на границе страницы (например, "`tst.l ($fff)` " где защищена страница, начиная с адреса $1000). Т.к. это не применимо к процессорам 68000, то Вы скорее всего никогда не столкнётесь с подобной ситуацией.
  - блокированные перемещения типа `tas`, `cas` или`cas2` не поддерживаются и создадут реальную Ошибку Доступа, но это не является проблемой, потому что эти команды не поддерживаются аппаратными средствами Амиги.
- 68040
  - эта конфигурация в данный момент не поддерживается
- 68060
  - Доступ к невыровненным данным не поддерживается и создаст Ошибку Доступа, невыровненный доступ - это доступ, который охватывает две страницы (и, по крайней, мере одна из них защищена), например, "`tst.l ($ffe)` " затрагивает страницу $0...$fff и страницу $1000...$1fff, это ограничение - настоящая проблема и является причиной того, что иногда невозможно использовать функцию resload_Protect. Я попытаюсь позже сделать поддержку этого, но это очень трудно.
  - невыровненные доступы потоков инструкций не поддерживаются и создают реальную Ошибку Доступа, если обе затронутые страницы защищены. В большинстве случаев, такую ситуацию можно обойти.
  - блокированные перемещения, вызванные `tas` или `cas` не поддерживаются и создают реальную Ошибку Доступа, но это не является проблемой, потому что эти команды не поддерживаются аппаратными средствами Амиги.
  - инструкции, которые находятся на защищенной странице (следовательно, эмулируемые) и доступ к функциям supervisor'а регистра статуса, будут выполнены неправильно, эти инструкции будут всегда видеть что trace bit выставлен в 1, а маска приоритета прерывания выставлена в 7, поэтому любое изменение функций supervisor'а не будет иметь никакого эффекта (т.е. supervisor останется без изменений).
  - `инструкция movem` может получить доступ к защищенной области, не создавая исключение "Ошибка Доступа", это возможно, потому что только первое обращение (слово или длинное слово) будет проверено на соответствие защищенной области.
  - `инструкция move16` и операции с плавающей запятой (FPU) не поддерживаются и создают Ошибку Доступа.
  - Команда "`move (mem),(mem)`" с перекрывающимися адресами источника и назначения, создаёт Ошибку Доступа, т.к. Misalignment будет выполняться некорректно, например "`move.l ($ffc), ($ffe)`", где страница $1000...$1fff защищена и память перед выполнение содержит ($ffc) =$11112222, ($1000) =$33334444, а после выполнения, $1000 содержит $11114444, а не $22224444.