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 тысяч тактов, которые так мешали сделать ваш эффект на инт быстрее.