ЧТОБЫ СТРОКА ВМЕЩАЛА БОЛЬШЕ...
Наверноe многие из вас сталкивались с
нехваткой места в строке для вывода
информации: в строке умещалось 32 символа
стандартного фонта (8*8). No проблемa эта
относительно легко разрешима. В принципе,
можно выводить до 80 символов в строке.
Своеобразными стандартами, что ли, в
данной области являются 64 и 42 символа в
строке (80 символов в строке используются
редко, т.к. даже на хорошем мониторе
разобрать текст становится
затруднительно). Итак, начну, пожалуй, с
64 символов. При выводе в 64 символа в
строке в каждый байт помещается по два
символа 64-го фонта(против одного байта
32-го), следовательно символ 64-го фонта
должен иметь размеры 4*8, т.к. в высоту он
такой же как и его 32-ой собрат(фактически
же, символ задается матрицей 3*7, т.к.
справа и снизу должно быть свободное
место, иначе вместо текста мы увидим
абстрактную картину). Можно задать фонт
стандартно: один символ - 8 байт, т.е.
весь фонт (все 256 символов) займет 2048
байт, однако можно уменьшить его размеры в
два раза, если задействовать пустое место.
Тогда фонт будет выглядеть так: 2 символа
8 байтов, и фонт займет лишь 1024 байта,
однако выводить его будет сложнее. Итак,
прикинем: надо вывести символ на экран,
при длине строки в 64 символа и ужатом
фонте(т.е. фонте в 1024 байта).
Для этого надо :
1. Вычислить адрес символа в фонте
2. Вычислить адрес вывода
3. Вывести символ
1. Адрес вычисляется довольно просто:
делим код символа на два, находим адрес
сдвоенной матрицы, далее проверяем на
четность код символа (который был до
деления) - если четный, то левая половинка
байта, если нечетный - правая.
2. Адрес вывода берем из таблицы
3. Данный этап целесообразно разбить на
две части, в зависимости от того, в какую
половинку байта на экране мы будем
выводить символ:
а) Для левой половинки.
Нечетный символ - никуда не двигаем,
берем байт по адресу вывода, объединяем по
логическому "и" (AND с маской %00001111 -
то что справа, нам менять не стоит. Берем
байт из матрицы символов, объединяем по
AND с %11110000, объединяем по логическому
"или" (OR) с тем что получили раньше, и
"кладем" на экран.
Четный символ - надо объединить по AND с
%00001111, сдвинуть влево на 4, проделать
то же с байтом адреса вывода, что и для
четного объединить по OR с предыдущим
результатом, и "положить" на экран.
б) Для правой половинки.
Тоже что и для левой, только надо будет
сдвигать левую часть направо, и маска для
экранной области будет %11110000.
Ну вот, "загрузил" я вас запутанной
теорией, пора бы ее подкрепить практикой.
В качестве примера будет процедурка
выводящая 64-ым шрифтом текст.
0RG #61A8
LD HL,TABLE ;заполняем таблицу
LD DE,0
LD B,24
CALL ZAPTAB
LD HL,TЕXT ;адрес текста в HL
LD BC,0 ;B - Y,C - X координта
; в текстовых значениях
WR_64 PUSH IX ;он нам еще пригодится
WR_64R PUSH BC
LD A,B ;смещение в таблице
ADD A,A
ADD A,A
ADD A,A
LD E,A
LD D,0
LD IX,TABLE ;находим адрес, по ко-
;торому находится адрес
;вывода.
ADD IX,DE
ADD IX,DE
WR_641 LD A,(HL) ;берем символ
INC HL
AND A ;ноль - конец текста
JR Z,OUTBTEN
CP 22 ;команда AT
JR Z,WR_6471
CP #0D ;перевод строки
JR Z,WR_64OL
CALL PS_64 ;вывод левой половинки
WR_64N LD A,(HL) ;берем следующий символ
INC HL
AND A ;аналогично
JR Z,OUTBTEN
CP 22
JR Z,WR_6471
CP #0D
JR Z,WR_64OL
CALL PR_64 ;вывод правой половинки
INC C ;переход к следущему байту
;в строке на экране
JR WR_641 ;и все по новой
WR_64OL POP BC ;следущая строка
INC B
JR WR_64R
OUTBTEN POP BC ;конец вывода
POP IX
RET
WR_6471 POP BC ;переход к произвольной
;позиции вывода
LD B,(HL)
INC HL
LD C,(HL)
INC HL
JR WR_64R
;ВЫВОД В ЛЕВУЮ ПОЛОВИНКУ БАЙТА
; A - КОД СИМВОЛА
; IX - ТАБЛИЦА АДРЕСОВ ВЫВОДА
PS_64 PUSH HL ;то, что нужно - сохраняем
PUSH IX
LD L,A ;/2*8=*4
SRL L
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,FONT
ADD HL,DE
EX DE,HL ;в DE адрес матрицы символа
SRL A ;проверка на четность
LD B,8 ;8 байт выводить
JR C,PS_642 ;нечет
LD A,(IX) ;адрес вывода на экран
LD H,(IX+1)
PUSH BC
ADD A,C
LD L,A
PS_641 LD A,(HL) ;мучаем байт с экрана
AND #0F
LD C,A
LD A,(DE) ;мучаем выводимый байт
AND #F0
OR C ;объединяем их
LD (HL),A ;кладем на экран
INC DE
INC H
DJNZ PS_641 ;повторяем
POP BC
POP IX
POP HL
RET
PS_642 LD A,(IX) ;берем адрес вывода
LD H,(IX+1)
ADD A,C
PUSH BC
LD L,A
PS_6422 LD A,(DE) ;выделяем правый кусок
AND #0F
RLA ;двигаем его влево
RLA
RLA
RLA
LD C,A
LD A,(HL) ;а здесь все по-старому
AND #0F
OR C
LD (HL),A
INC DE
INC H
DJNZ PS_6422
POP BC
POP IX
POP HL
RET
;ПРОЦЕДУРА ВЫВОДА В ПРАВУЮ ПОЛОВИНКУ ЭК-
;РАННОГО БАЙТА
;НА ВХОД В A - КОД СИМВОЛА
; В IX - ТАБЛИЦА АДРЕСОВ ВЫВОДА
PR_64 PUSH HL ;ВСЕ АНАЛОГИЧНО ПРЕДЫУЩЕМУ
;СЛУЧАЮ
PUSH IX
PUSH BC
LD L,A
SRL L
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,FONT
ADD HL,DE
EX DE,HL
SRL A
LD B,8
JR C,PR_642
LD A,(IX)
LD H,(IX+1)
ADD A,C
LD L,A
PR_641 LD A,(HL) ;байт с экрана будем
AND #F0 ;мучать
LD C,A
LD A,(DE) ;четный придется двигать
SRL A
SRL A
SRL A
SRL A
OR C
LD (HL),A ; а дальше все ясно
INC DE
INC H
DJNZ PR_641
POP BC
POP IX
POP HL
RET
PR_642 LD A,(IX)
LD H,(IX+1)
ADD A,C
LD L,A
PR_6422 LD A,(HL) ; тут вроде все ясно
AND #F0
LD C,A
LD A,(DE)
AND #0F
OR C
LD (HL),A
INC DE
INC H
DJNZ PR_6422
POP BC
POP IX
POP HL
RET
;процедура заполнения таблички
ZAPTAB LD A,D
LD C,A
AND A
DUP 3
RRCA
EDUP
AND #E0
ADD A,E
EX AF,AF'
LD A,C
AND #18
OR #40
EX AF,AF'
LD C,A
EX AF,AF'
DUP 8
LD (HL),C
INC HL
LD (HL),A
INC A
INC HL
EDUP
INC D
DJNZ ZAPTAB
EI
RET
;выводимый текст
TEXT DEFB "ПРИВЕТ ВСЕМ !!!",#0D,#0D
DEFB "HELLO TO ALL!!!",0
;здесь будет фонт
FONT INCBIN "A:FONT48a.C"
;а здесь таблица адресов
TABLE
Эта процедура вывода занимает довольно
много времени, ее можно заметно ускорить
если сделать два набора символов:
сдвинутый влево и сдвинутый вправо, при
этом отпадает надобность что-то куда-то
двигать:
ORG #61A8
CALL RAZPAC ;превращаем один ужатый
;фонт в два разжатых
LD HL,TABLE ;аналогично предыдущему
LD DE,0 ;случаю
LD B,24
CALL ZAPTAB
LD HL,TEXT
LD BC,0
LD IX,TABLE
WR_64 PUSH IX
WR_64R PUSH BC
LD E,B
LD D,0
LD IX,TABLE
ADD IX,DE
ADD IX,DE
WR_641 LD A,(HL)
INC HL
AND A
JR Z,OUTBTEN
CP 22
JR Z,WR_6471
CP #0D
JR Z,WR_64OL
CALL PS_64
WR_64N LD A,(HL)
INC HL
AND A
JR Z,OUTBTEN
CP 22
JR Z,WR_6471
CP #0D
JR Z,WR_64OL
CALL PR_64
INC C
JR WR_641
WR_64OL POP BC
LD A,8
ADD A,B
LD B,A
JR WR_64R
OUTBTEN POP BC
POP IX
RET
WR_6471 LD B,(HL)
INC HL
LD C,(HL)
INC HL
JR WR_64R
;ВЫВОД В ЛЕВУЮ ПОЛОВИНКУ БАЙТА
; A - КОД СИМВОЛА
; IX - ТАБЛИЦА АДРЕСОВ ВЫВОДА
PS_64 PUSH HL
PUSH IX
LD L,A ;делить на 2 не надо
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,FONTL ;левая половинка -
;левый фонт
ADD HL,DE
EX DE,HL
LD A,(IX)
LD H,(IX+1)
PUSH BC
ADD A,C
LD L,A
LD B,8
PS_641 LD A,(HL) ;ловкость рук и никаких
AND #0F ;RRCA
LD C,A
LD A,(DE)
OR C
LD (HL),A
INC DE
INC H
DJNZ PS_641
POP BC
POP IX
POP HL
RET
;ПРОЦЕДУРА ВЫВОДА В ПРАВУЮ ПОЛОВИНКУ ЭК-
;РАННОГО БАЙТА
;НА ВХОД В A - КОД СИМВОЛА
; В IX - ТАБЛИЦА АДРЕСОВ ВЫВОДА
PR_64 PUSH HL
PUSH IX
PUSH BC
LD L,A
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,FONTR ;правая половинка -
ADD HL,DE ;правый фонт
EX DE,HL
LD B,8
LD A,(IX)
LD H,(IX+1)
ADD A,C
LD L,A
PR_6422 LD A,(HL) ;и ничего не двигаем
AND #F0
LD C,A
LD A,(DE)
OR C
LD (HL),A
INC DE
INC H
DJNZ PR_6422
POP BC
POP IX
POP HL
RET
;ПРОЦЕДУРА РАЗЖИМАЮЩАЯ ФОНТ
RAZPAC LD HL,FONT1 ;исходный фонт
LD DE,FONTL ;левый фонт
LD BC,#8000 ;128 символов в ужатом
EXX ;фонте
LD HL,FONTR ;правый фонт
LD DE,FONTL+8 ;следующий символ
LD BC,FONTR+8 ;следующий символ
EXX
RAZPAC2 LD C,8 ;а байт то в символе 8 !
RAZPAC1 LD A,(HL) ;начнем-с
PUSH AF
AND #F0 ;левый символ
LD (DE),A
INC DE
EXX
AND A ;двигаем
DUP 4
RRCA
EDUP
LD (HL),A ;в правый фонт
INC HL
POP AF
AND #F ;правый символ
LD (BC),A ;в след. символ левого
INC BC ;фонта
DUP 4 ;двигаем
RLCA
EDUP
LD (DE),A ; в след. символ правого
INC DE ;фонта
EXX
INC HL
DEC C
JP NZ,RAZPAC1 ;разжимаем символ
PUSH HL
LD HL,8 ;переходим к следующему
ADD HL,DE ;символу ужатого фонта
EX DE,HL
POP HL
EXX
LD HL,8
ADD HL,DE
EX DE,HL
LD HL,8
PUSH BC
AND A
ADC HL,BC
LD C,L
LD B,H
POP HL
EXX
DJNZ RAZPAC2
RET
;ПРОЦЕДУРА ЗАПОЛНЯЮЩАЯ ТАБЛИЦУ ВЫВОДА
ZAPTAB LD A,D
LD C,A
AND A
DUP 3
RRCA
EDUP
AND #E0
ADD A,E
EX AF,AF'
LD A,C
AND #18
OR #40
EX AF,AF'
LD C,A
EX AF,AF'
DUP 8
LD (HL),C
INC HL
LD (HL),A
INC A
INC HL
EDUP
INC D
DJNZ ZAPTAB
EI
RET
TEXT DEFB "ПРИВЕТ ВСЕМ !!!",#0D,#0D
DEFB "HELLO TO ALL!!!",0
TABLE
FONT1 INCBIN "A:FONT48a.C"
DEFS 1256
FONTL DEFS #800
FONTR DEFS #800
Способ, конечно, не экономичный, зато
быстрый. Ну, с 64-ым фонтом разобрались, а
о 42-ом фонте раскажу в следующий раз.
(c)Trusov Ilya