Из журнала Info Guide #7, Рязань, 06.2005 384x304: программирование Эта статья написана по просьбе Znahar/Rush и служит дополне- нием к статье в AlCoNews#32. Перепечатывать ту статью целиком не буду, лучше найдите оригинал. Схема устройства (Contact v2.06 by Alone Coder & KSA-7G) Первая цепь (как и в схеме с рубильником):
Вторая цепь (вместо рубильника):
Адреса полей экрана для основного экрана: {Адреса атрибутов - в фигурных скобках} {#d0xx} #c01f|#e000 ^ {#f0xx} #e01f|#c008 {#d0xx} ... | ... 8chr ... | ... #c7ff|#e7e0 v #e7ff|#c7e8 -------------+------------------------------------+------------- {#58xx} #401f|#6000 ^ {#78xx} #601f|#4008 {#58xx} ... ... | ... | ... ... | ... ... | 24chr | ... ... | ... | ... ... | ... ... {#5axx} #57ff|#77e0 v {#7axx} #77ff|#57e8 {#5axx} -------------+------------------------------------+------------- {#d3xx} #d81f|#f800 ^ {#f3xx} #f81f|#d808 {#d3xx} ... | ... 6chr ... | ... <---8chr---> |#ffa0 v #ffbf| <---8chr---> Поскольку 0-я и 1-я трети (точнее, не трети, а пятые доли) отличаются по адресации пикселов только страницами, но при этом сильно отличаются по адресации атрибутов, то запишу только вари- анты процедур для случая, когда открыта 4-я страница, а экран - основной. Программу для 384x304 лучше всего писать так, чтобы в ней был и стандартный режим 256x192. Для этого нужно: 1. Во всех случаях выделить память #6000..#7aff и часть 4-й страницы. 2. Для 384x304 использовать эти области под экран. 3. Для 256x192 использовать эти области, например под буфер развёрнутого шрифта (как в ACE ). 4. При написании или переделке программы размеры экрана иметь в особых константах, чтобы их можно было сменить. 5. Процедуры печати написать для 256x192 и 384x304 разные или одинаковые, но с учётом разного размера экрана (если активное поле на 384x304 будет регулируемым, то вообще прекрасно :)). 6. После отладки процедур вместо ручной смены констант (и ве- ток условной компиляции) в исходнике организуйте переменные про- граммы, по которым сама программа будет подстраиваться. Для каж- дого параметра (ширина,высота, адрес процедуры печати...) должно быть ровно одно место хранения, а процедуры должны будут исполь- зовать информацию из этого места (то есть из переменной). Менять переменные на начальном этапе можно через константу в исходнике. 7. Потом и эту константу уберите, взамен сделайте сетап. 8. Дисковые операции и другие сложные меню проще организовать на экране 256x192 (как в ACE и ANSI ). Однако, если режим не будет меняться, будет лицеприятнее... 9. Экран нужно очищать сверху вниз, иначе получается некрасиво (процедуру переброски строки см. в AlCoNews#32, но можете воспо- льзоваться приведённой здесь процедурой CLS384 ). 10. Видимыми везде считаются по 4 знакоместа с боков основного экрана, плюс ещё 4 сверху и ещё 2 снизу. Так сделано в новых версиях Unreal Speccy, считаю, правильно. В ACN#32 я предлагал использовать по 3 знакоместа сверху и снизу, но не подумал, что это было несимметрично (то есть никакого отношения к реальной видимости на ТВ не имело). Если поддержите 2 экрана, то в будущем сможете поддержать и другие, а их много на разных клонах! Особенно заманчиво выглядит экран 512x192 - он занимает те же адреса #6000..#77ff. Процедуры работы с экраном 384x304 (они же !384.H в приложении) ;0. on&off 384X304 OFF384 XOR A JR $+4 ON384 LD A,64 LD BC,#EFF7 OUT (C),A RET ;1. byte right ;ищет следующий справа байт экрана BR384 LD A,L INC L XOR L AND 32 RET Z ;46 раз из 48 BIT 5,H JR Z,br384c ;1 раз из 48 RES 5,H ;1 раз из 48 LD A,-24 JR br384al br384c SET 5,H LD A,-32 br384al ADD A,L LD L,A RET ;2. y -> scr ;BC указывает порядковый номер строки (от 0 до 303) ;на выходе HL=базовый адрес строки (#4000 вместо #4018 и т.п.) ;не портит BC YSC384 LD A,C AND 7 LD H,A XOR C ADD A,A,A,A LD L,A LD A,#D8 INC B DJNZ ys384LO LD A,C AND #C0 RRCA RRCA RRCA JR NZ,$+4 LD A,#C0-#38 ;0-я треть ADD A,#38 ys384LO ADD A,H LD H,A RET ;3. xy -> scr ;BC указывает порядковый номер строки (от 0 до 303) ;E - номер байта в строке (от 0 до 47) ;на выходе HL=адрес этого байта XYSC384 CALL YSC384 ;y -> scr LD A,E SUB 8 JR C,xs384l CP 32 JR C,xs384m SUB 32+#18 xs384l ADD A,8+#18 JR xs384al xs384m SET 5,H xs384al ADD A,L LD L,A RET ;4. scr -> attr ;процедура работоспособна при любом полож. HL внутри знакоместа SA384 LD A,H AND #C0+24 JP P,$+5 ADD A,#86-#C0-#C2+#40 ;#86 после прокрутки будет #D0 ADD A,#C2-#40 ;#C2 после прокрутки будет #58 RRCA RRCA RRCA XOR H AND #DF XOR H LD H,A RET ;5. down hl DH384 INC H LD A,H AND 7 RET NZ ;266 раз из 304 LD A,L ADD A,32 LD L,A LD A,H JR C,dh384nd ;34 раза из 304 SUB 8 LD H,A RET dh384nd AND #DF CP #58 RET C ;2 раза из 304 SET 7,H ;переход на последнюю (4-ю) треть RET Z ;1 раз из 304 XOR H ;#00/#20 OR #40 ;переход на основной экран (1-ю треть) LD H,A RET ;6. clear screen (сверху вниз!) ;A=атрибут CLS384 LD HL,#C018 LD BC,304 LD LX,A CLS3840 PUSH BC PUSH HL XOR A CALL CLS384L POP HL PUSH HL CALL SA384 LD A,LX CALL CLS384L POP HL POP BC CALL DH384 DEC BC LD A,B OR C JR NZ,CLS3840 RET CLS384L LD BC,7 CALL FILHL EXA LD A,L SUB 7+16 LD L,A EXA LD C,7 CALL FILHL EXA SUB 8 LD L,A EXA SET 5,H LD C,31 FILHL LD D,H,E,L INC E LD (HL),A LDIR RET ;7. рисование окна (с очисткой его содержимого) ;HL=адрес на экране ;B=width-1, C=hgt*8-2 WIN384 PUSH HL LD E,-1 LD (HL),E CALL HOR384 JR WIN384P WIN3840 PUSH HL LD (HL),128 LD E,0 CALL HOR384 LD (HL),1 WIN384P POP HL CALL DH384 DEC C JR NZ,WIN3840 LD E,-1 LD (HL),E HOR384 PUSH BC HOR3840 CALL BR384 LD (HL),E DJNZ HOR3840 POP BC RET A. Coder