Info Guide
#11
05 июля 2015 |
|
Code - Этюды: Вызов функции по номеру, Поиск текста по номеру, Определение наличия музыкального сопроцессора, Установка пикселя на ATM Turbo 2, Библиотеки процедур в ALASM, Короткий генератор случайных чисел, Ускорение LD:PUSH.
Этюды Alone Coder 1. Вызов функции по номеру а)если номера идут не подряд: ;HL=список функций ;(номер, смещение адреса), ;0=конец списка, т.е. функции 0 нет ;C=номер функции #1624 CALL #1бDC RET NC;функция не найдена LD D,0 LD E,(HL);смещение адреса функции ADD HL,DE JP (HL) ... #1бDB INC HL #1бDC LD A,(HL) AND A RET Z;конец списка,функция не найдена CP C INC HL JR NZ,#1бDB SCF RET ;пример списка функций: DB 1 DB 255&(func1-$) DB 10 DB 255&(func10-$) DB 0;конец списка ;сами функции рядом: func1 ... RET func10 ... RET б)если номера функций идут подряд (1,2, ...): ;B=номер функции DJNZ nofunc1 <func1> RET nofunc1 DJNZ nofunc2 <func2> RET nofunc2 ... ;у последней функции номер не проверяется ;(может быть 0) <funcO> RET 2. Поиск текста (например, сообщения) по номеру а)вариант из ACEdit: ;HL=указатель на список текстов ;(каждый текст кончается на 0) ;D=номер текста (1..n) ;возвращает HL = указатель на нужный текст LD B,H;достаточно большое число XOR A;символ конца текста DEC D RET Z CPIR;ищем символ конца текста ;и ставим HL после него JR $-4 б)вариант в ПЗУ 48 Basic (только для ASCII, т.к. 7-й бит занят под признак конца текста): ;DE=указатель на список текстов ;(каждый с установленным 7-м битом ;в последнем символе) ;A=номер текста (0..n) ;возвращает DE = указатель на нужный текст #0C41 PUSH AF EX DE,HL INC A #0C44 BIT 7,(HL) INC HL JR Z,#0C44 DEC A JR NZ,#0C44 EX DE,HL POP AF cp #20 ;это ret c ;для ld a,(de);нас sub #41 ;не важно RET ;пример списка текстов: #0095 DB #BF ;любой байт с установленным ;7-м битом (будет пропущен) DB "RN","D"+#80 DB "INKEY","$"+#80 ... 3. Определение наличия музыкального сопроцессора LD BC,#FFFD XOR A;A=0/2/4/7/11 (полные 8-битные) OUT (C),A;избегаем OUT (C),0 IN L,(C);oldRO INC L LD B,#BF OUT (C),L;newRO != oldRO ;читать R0 и проверить, изменился ли он LD B,#FF;#fdfd нельзя на ATM1 IN A,(C);R0 CP L;newRO JR Z,AY_ON;R0 == newRO AY_OFF Кто придумает короче без потери совмес─ тимости? 4. Установка пикселя в режиме 320x200 на ATM Turbo 2 Поскольку X-координата не помещается в одном байте, отрежем младший бит в отдель─ ный регистр. ;setpixel (EGA screen) ;страницы экрана - в двух окнах памяти ;addr = tY(y) + tX(x) ;l=x ;e=y ;lx=xlow mask ;d='tY ;h='tX LD A,(DE);(y*40) ADD A,(HL);x div 4 LD C,A INC D INC H LD A,(DE);'(y*40) ADC A,(HL);f(x mod 4) LD B,A LD A,(BC) (X)OR LX;xlow mask LD (BC),A DEC D INC H ;74(66) t-states (ср.62(58) такта на 6912, см. ZX-Guide #1) Таблицы подготавливаются так: LD HL,#4000;экран в #4000 и #c000 LD BC,40 LD E,B mktyO LD D,'tY LD A,L LD (DE),A INC D LD A,H LD (DE),A ADD HL,BC INC E JNZ mktyO mktxO LD D,'tX LD A,E RRA RRA AND #3F LD (DE),A INC D LD A,E RRCA AND #80 BIT 2,E JZ $+4 OR #20 LD (DE),A;#00,#80,#20,#a0 INC E JNZ mktxO В Nedodemo 2 использовался вариант это─ го метода приX=0..255: ;l=x ;e=y ;d='tY LD H,'tX LD A,(DE);(y*40) ADD A,(HL);x div 4 LD C,A INC D INC H LD A,(DE);'(y*40) ADC A,(HL);f(x mod 4) ;#00,#00,#80,#80,#20,#20,#a0,#a0 LD B,A INC H;'tXmask LD A,(BC) (X)OR (HL);xlow mask LD (BC),A DEC D ;80(76) t-states В генераторе таблиц надо добавить тре─ тийRRA, второй RRCA, заменить #3F на #1F и вставить передLD (DE),A: INC D LD A,E RRA SBC A,A XOR %01000111;left pixel AND C 5. Библиотеки процедур в ALASM Если надо сделать библиотеку процедур, каждая из которых будет компилироваться только тогда,когда используется в програм─ ме, то можно пойти такими путями: а)создать макросы на каждую процедуру: INCLUDE "math",pgmath ... MUL _MUL DIV _DIV math.h: MACRO _MUL ;процедура умножения RET ENDM MACRO _DIV ;процедура деления RET ENDM б)один и тот же модуль инклюдить неско─ лько раз - по одному для каждой процедуры. Это эффективнее по памяти, чем макросы (где может просто переполниться страница макросов), но скорость не гарантируется: ... MUL INCLUDE "math",pgmath DIV INCLUDE "math",pgmath ... math.H: IFN ?mathtwice const1=1 const2=2 ... MACRO mathbla ... ENDM mathtwice ENDIF IFO ?MUL;если метка определена IFN ?MULcompiled ;процедура умножения RET MULcompiled ENDIF ENDIF IFO ?DIV;если метка определена IFN ?DIVcompiled ;процедура деления RET DIVcompiled ENDIF ENDIF в)инклюдить все библиотеки в самом кон─ це, чтобы они сами могли проверять, какие процедуры используются, какие нет: ... CALL MUL CALL DIV ... INCLUDE "math",pgmath math.h: IFN ?MUL;если к метке обращались MUL ;процедура умножения RET ENDIF IFN ?DIV;если к метке обращались DIV ;процедура деления RET ENDIF 6. Короткий генератор случайных чисел (прислал Tiboh) EXX INC HL RES 3,H LD A,R XOR (HL) EXX 7. Ускорение LD:PUSH Обычный код вывода на экран типаLD DE: PUSH DE неудачно ложится на задержки в фи─ рменных машинах (4 восьмитактовых цикла). Если же есть свободный регистрBC, то можно выиграть в скорости, переписав так: LD BC,nn LD DE,nn PUSH BC PUSH DE Это занимает 7 восьмитактовых циклов,то есть 3.5 на каждыйPUSH. Добавление регистраHL в общем невыгод─ но (11 восьмитактовых циклов на триPUSH), но если постараться загнать группуPUSH в поле бордера, можно чего-то добиться.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября