Из журнала Deja Vu #05, Кемерово, 01.07.98 В текст внесены исправлениями из DV #06 (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 INT1 DI LD (TOSP+1),SP LD SP,INT1 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 AND A SBC HL,DE LD A,#C9 ; RET JR NZ,OK LD A,#C3 ; JP OK 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 EX (SP),HL LD (_JP+1),HL POP HL LD (TOSP2+1),SP LD SP,INT2 PUSH HL PUSH DE PUSH BC PUSH AF PUSH IX EXX EX AF,AF PUSH HL PUSH DE PUSH BC PUSH AF PUSH IY ... обработка прерывания POP IY POP AF POP BC POP DE POP HL EXX EX AF,AF POP IX POP AF POP BC POP DE POP HL TOSP2 LD SP,0 EI _JP JP 0 Рассмотрим возможные случаи, когда мо- жет произойти прерывание : а) между командами POP HL и LD (NN),HL считываемые байты находятся в регистрах HL и перед возвратом будут записаны командой PUSH HL. б) между командами LD (NN),HL и POP HL данные опять же находятся в HL и восстано- вятся точно таким же способом. Стоит заметить,что возврат из этого об- работчика всегда будет совершаться прямым переходом. Замечу,что в демонстрациях такие обход- ные трюки со стеком я еще не встречал. Я надеюсь, что эта статья уменьшит ра- боту некоторых ваших эффектов на лишние 10-20 тысяч тактов, которые так мешали сделать ваш эффект на инт быстрее.