Код:
//_____________________________________________________________________________
//
// Процедура реализации алгоритма работы ROM 1801РЕ2
// - не осуществляет возврат (работает постоянно)
// - выполняется с запрещенными прерываниями (не используются)
// - код позиционно-независимый - работает перемещенным в RAM
//
// Входные параметры:
// R0 - адрес таблицы ссылок на банки ROM
// R1 - адрес порта шины данных
// R2 - адрес порта сигналов управления
//
#define PIO_IDR 0x10 // смещение регистра входных данных
#define PIO_ODR 0x14 // смещение регистра выходных данных
#define PIO_BSR 0x18 // смещение регситра сброса и установки
//
#define RPLY_BIT 0 //
#define SYNC_BIT 3 //
#define DIN_BIT 13 //
#define SEL0_BIT 9 //
#define SEL1_BIT 4 //
#define SEL2_BIT 5 //
#define SEL3_BIT 7 //
//
#define RPLY_MSK (1<<RPLY_BIT) //
#define SYNC_MSK (1<<SYNC_BIT) //
#define DIN_MSK (1<<DIN_BIT) //
#define SEL0_MSK (1<<SEL0_BIT) //
#define SEL1_MSK (1<<SEL1_BIT) //
#define SEL2_MSK (1<<SEL2_BIT) //
#define SEL3_MSK (1<<SEL3_BIT) //
#define SELX_MSK ((1<<SEL0_BIT) | (1<<SEL1_BIT) | (1<<SEL2_BIT) | (1<<SEL3_BIT))
_sect(.text, CODE, "ax", 2) //
_global app_rom_loop //
_global app_end_loop //
_thumb //
_thumb_func //
//
app_rom_loop: mov R12, R0 // R12 - таблица ссылок
movs R5, #RPLY_MSK // вспомогательная константа
//
// Для начала цикла ожидаем высокий уровень SYNC (неактивный)
//
@@SyncHigh: ldr R0, [R2, #PIO_IDR] // загружаем управляющие
movs R0, R0, lsr #(SYNC_BIT+1) // сигналы и проверяем
bcc.n @@SyncHigh // сигнал SYNC
//
// Теперь ожидаем низкий уровень SYNC (ниспадающий фронт)
//
@@SyncFall: ldr R7, [R1, #PIO_IDR] // R7 предполагаемый адрес
ldr R4, [R2, #PIO_IDR] // для предварительной фиксации
movs R0, R4, lsr #(SYNC_BIT+1) //
bcs.n @@SyncFall //
//
// Выполняем подготовку обращения к таблице ссылок
// Выделяем старшие три бита chipcode и вычисляем
// элемент таблицы
//
movs R0, R7, lsr #13 // в R6 указатель на элемент
add R6, R12, R0, lsl #8 // таблицы соответствующей
ubfx R7, R7, #1, #12 // зафиксированному chipcode
movs R7, R7, lsl #1 //
//
// Обнаружен ниспадающий фронт SYNC, теперь будем проверять
// устойчивой комбинации SYNC=0, DIN=0, и некоторых активных
// сигналов выборки
//
// Как оказалось если в качестве сигнала CS используется выход
// с микросхем 1801ВП1 (в частности -037) то к моменту ниспадающего
// SYNC матрица еще не успевает декодировать адрес и РЕ-мулятор
// не получает устойчивой комбинации сигналов на входе. Поэтому
// выполняем ожидание
//
@@WaitSel: ldr R4, [R2, #PIO_IDR] // загружаем управляющие
movs R0, R4, lsr #(SYNC_BIT+1) // сигналы и проверяем
bcs.n @@SyncFall // сигнал SYNC
movs R0, R4, lsr #(DIN_BIT+1) // проверим активность
bcs.n @@WaitSel // сигнала DIN
ubfx R0, R4, #SEL1_BIT, #6 //
ldr R3, [R6, R0, lsl #2] //
tst R3, R3 // при данной комбинации
beq.n @@WaitSel // нет доступа к ROM
//
// Более быстрый вариант, но требует чтобы комбинация CS была
// устойчивой в момент ниспадающего SYNC
//
// ubfx R0, R4, #SEL1_BIT, #6 //
// ldr R3, [R6, R0, lsl #2] //
// tst R3, R3 // при данной комбинации
// beq.n @@SyncHigh // нет доступа к ROM
//
ldrh R0, [R3, R7] // выполняем загрузку
// данных из массива
@@WaitDin: ldr R4, [R2, #PIO_IDR] // теперь ждем активного DIN
movs R3, R4, lsr #(DIN_BIT+1) //
ittt cc //
movcc R4, R5, lsl #16 //
strcc R4, [R2, #PIO_BSR] // активируем сигнал RPLY
strcc R0, [R1, #PIO_ODR] // выводим данные на шину
bcc.n @@SetupWait //
movs R3, R4, lsr #(SYNC_BIT+1) //
bcc.n @@WaitDin //
b.n @@SyncFall //
//
@@SetupWait: movs R3, #0xFFFFFFFF //
movs R3, R3, lsr #16 //
//
@@WaitDone: ldr R0, [R2, #PIO_IDR] // проверим активность DIN
movs R4, R0, lsr #(DIN_BIT+1) // как только DIN неактивен
bcc.n @@WaitDone // сразу снимаем RPLY и
str R5, [R2, #PIO_BSR] // освобождаем шину
strh R3, [R1, #PIO_ODR] //
b.n @@SyncHigh //
//
app_end_loop: //
//
//_____________________________________________________________________________
//
Исходники все открыты, смотрим файл a205.a79 - это ассемблерный модуль, в том числе содержит саму процедуру эмуляции. Позиционно-независима, исполняется копия процедуры в RAM, так как в целом быстрее чем из флеша, несмотря на кеширующий акселератор. В исходниках достаточно подробные комментарии, если что-то конкретно непонятно - спрашивайте. Блок-схему - постараюсь, но это времени требует, да и очень редко их рисую, только на бумажке.