SoundTrack: SECTOR/SERIOUS S.G.'97 (CMG98)
__________________________________________
(C) RLA/CRG
__________________________________________
ИСПОЛЬЗОВАНИЕ СТЕКА
ПРИ РАЗРЕШЕННЫХ ПРЕРЕЫВАНИЯХ
Не секрет, что для быстрых манипуляций
с графикой в играх и, особенно, в демонст-
рациях, широко используются команды работы
со стеком. Именно с их помощью можно дос-
тичь наибольшей скорости работы с графи-
кой. Но, чем круче эффект, тем больше вре-
мени он занимает. Возможны случаи, когда
эффект не успевает отработать 69888 тактов
и происходит прерывание. Адрес возврата
выкидывается на стек и безвозвратно портит
содержащуюся под ним информацию. Но не все
потеряно. Рассмотрим несколько случаев,как
можно сохранить эти данные и работать со
стеком с включенными прерываниями второго
рода.
1. Если происходит очистка или заполне-
ние экрана какими-либо данными, то это не
так страшно,ибо при возврате из прерывания
продолжится цикл PUSH HL и адрес возврата
будет затерт нужными данными.
1.1 Возможно,что стек будет равен 4000h
и адрес возврата будет потерян, но этот
случай можно проконтролировать, если знать
адреса тех точек, в которых это может слу-
читься и перейти туда не по RET'у,а JP AD-
DRESS.
Пример:
LD SP,#4020 ;чистим самую
LD HL,#0000 ;верхнюю линию
PUSH HL ;в экране
PUSH HL
PUSH HL
... *16 раз
PUSH HL
PUSH HL
ADR1 LD SP,(SAVESP)
RET
Последний случай возможен, если преры-
вание вклинится между командами PUSH HL и
LD SP,(SAVESP). Обработчик 2 (!) прерыва-
ний в таком случае будет выглядеть так :
ORG #BFBF
INT2 DI
LD (TOSP+1),SP
LD SP,INT2-1
PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH IX
EXX
EX AF,AF
PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH IY
LD HL,(TOSP+1)
LD DE,-#4000
ADD HL,DE
LD A,#C9 ; RET
JR C,OK
LD A,#C3 ; JP
LD (TO_RET),A
... обработка прерывания
POP IY
POP AF
POP BC
POP DE
POP HL
EXX
EX AF,AF
POP IX
POP AF
POP BC
POP DE
POP HL
EI
TOSP LD SP,0
TO_RET DB 0
DW ADR1
2. Есть еще один коварный случай, когда
данные при помощи стека не записываются, а
считываются. Чаще всего это употребляют,
когда на экране двигается большая его
часть (TRASH DEMO, ART'98,всевозможные ин-
тро к играм). В памяти заранее создается
большой спрайт и выводится на экран при-
мерно такой цепочкой байтов :
POP HL
LD (#4000),HL
POP HL
LD (#4002),HL
...
POP HL
LD (#57FE),HL
LD SP,(SAVESP)
RET
В приведенных программах часть экрана
успевает переброситься за одно прерывание,
и данная проблема не возникает, но бывали
случаи, когда работает один эффект,а потом
нужно сверху перекинуть окно с пожеланиями
или GTX'ами. Если произойдет прерывание,то
на стек опять же выкинется адрес возврата
и спрайт будет "безвозвратно" испорчен.
Именно с таким случаем ко мне обратился
один мой знакомый кодер. Спустя некоторое
время проблема была решена. Его эффекты
работали при разрешенных прерываниях, а
графика не портилась.
Обработчик:
ORG #BFBF
INT2 DI
LD (TOSP+1),SP
LD SP,INT2-1
PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH IX
EXX
EX AF,AF
PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH IY
LD HL,(TOSP+1)
LD E,(HL)
INC HL
LD D,(HL)
LD (_JP+1),DE
... обработка прерывания
POP IY
POP AF
POP BC
POP DE
POP HL
EXX
EX AF,AF
POP IX
POP AF
POP BC
POP DE
POP HL
TOSP LD SP,0
PUSH HL ;Запись
POP HL ;Корректировка стека
EI
_JP JP 0
Рассмотрим возможные случаи, когда мо-
жет произойти прерывание :
а) между командами POP HL и LD (NN),HL
считываемые байты находятся в регистрах HL
и перед возвратом будут записаны командой
PUSH HL.
б) между командами LD (NN),HL и POP HL
данные опять же находятся в HL и восстано-
вятся точно таким же способом.
Стоит заметить,что возврат из этого об-
работчика всегда будет совершаться прямым
переходом.
Замечу,что в демонстрациях такие обход-
ные трюки со стеком я еще не встречал.
Я надеюсь, что эта статья уменьшит ра-
боту некоторых ваших эффектов на лишние
10-20 тысяч тактов, которые так мешали
сделать ваш эффект на инт быстрее.