Покритикуйте такую идею для реализации критической секции. На emuverse.ru упоминается недокументированная команда LD DDD, rot [IX+d], которая производит битовый сдвиг байта в памяти и запись результата в регистр. Т.е. имеем две операции в рамках одной атомарной. Идея такова. Нулевой байт обозначает свободную секцию. Используем LD A, SLI [IX+d] (или SCF: LD A, RL [IX+d]). Поток, которые первый выполняет эту атомарную операцию занесет в секцию значение 1, последующие потоки будут заносить 3, 7, 15 и т.д., но никогда не 1. Т.е. наличие единицы в регистре A обозначает, что мы захватили секцию. Освобождение секции выполняется простым занесением нуля в секцию.
Код:
;; если флаг Z при выходе функции включен, то зашли в секцию
TryEnterCriticalSection:
LD A, SLI [IX]
DEC A
RET
EnterCriticalSection:
LD A, SLI [IX]
DEC A
JR NZ, $ - 5
RET
LeaveCriticalSection:
LD [IX], 0
RET
Update.
Что-то я слишком все усложнил. Можно и на документированных командах это сделать. 0x80 - значение свободной секции.
Код:
;; если флаг С при выходе функции включен, то зашли в секцию
TryEnterCriticalSection:
SLA (IX)
RET
EnterCriticalSection:
SLA (IX)
JR NC, $ - 4
RET
LeaveCriticalSection:
LD [IX], 0x80
RET