Из журнала 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