All of the printed characters, ...
(C) Cooper/RSM/P7S
Today is a rare program, especially systemic, do without it -
without printing characters.
On the Spectrum there are 4-D standard
fonts. They differ from each other wide
one character. These formats 8x8, 6x8, 5x8,
4x8 pixels. Consequently, the first format
we can put in one line on the screen
32 characters, the second - 42 characters, the third -
51 character, while the fourth - 64 characters. 5x8 matrix is
the least common among all the others.
What represents a block font?
The most common type consists of 256
character - or rather, because of their images.
One character, regardless of size
matrix is given by 8 bytes. For example,
this way is stored in the character set (hereafter - the font),
the letter "A":
adr: bin:
# C000 00000000
# C001 00111100
# C002 01000010
# C003 01000010
# C004 01111110
# C005 01000010
# C006 01000010
# C007 00000000
Not difficult to calculate that the entire font is in memory
of 2048 bytes.
Along with the usual linear fonts
There are so-called screen fonts. There is also
each character consists of eight bytes, the difference lies in
the same order they are found eight bytes of data symbols in a
block font (Oh, shit, and said;). For example, all the same
letter "A" will be stored like this:
adr: bin:
# C000 00000000
# C100 00111100
# C200 01000010
# C300 01000010
# C400 01111110
# C500 01000010
# C600 01000010
# C700 00000000
Note the address of occurrence
bytes in memory. Why is it necessary, I will tell
below, we will print these characters
on the screen.
Well, then, with the font format understood. Once again I
repeat: all the above refers to the standard fonts, because
There are non-standard fonts (6x7, packing, proportional fonts
for printing and others). Now, we will be shaped as letters of
our (Or Th we've got;) displayed on the screen.
For this we need a procedure that used recounted given us the
coordinates to the appropriate address in the screen area. Ie,
here's this ...
;========= Coordinates -> scr adr ========
; In: D - Y coordinate, E - X coordinate
; Out: DE - screen adress
LD A, D
AND 7
RRCA
RRCA
RRCA
OR E
LD E, A
LD A, D
AND 24
OR 64
LD D, A
We will not go into details, they say,
what, where and how it works, because is a common procedure and
is used everywhere.
Now consider the nuances of printing fonts with different
matrices ...
Print character 8x8
Characters with such a matrix display is easier
total. For example, in case A we have kept the character code,
and in DE - its coordinates on the screen. Then the procedure,
the print symbol of 8x8 points, will look like:
;===== Print character 8x8 color =====
; In: DE - coordinates, A - character code
Pr_Sym LD L, A
LD H, 0
ADD HL, HL; multiply the character code
ADD HL, HL; eight ...
ADD HL, HL
LD BC, font; ... and add to
ADD HL, BC; start address font
LD A, D; familiar to us already
AND 7; protsedurka;)
RRCA
RRCA
RRCA
OR E
LD E, A
LD A, D
AND 24
OR 64
LD D, A
LD B, 8
PRINT LD A, (HL); take a byte from the font
LD (DE), A; and put in a screen
INC HL; do increment
INC D
DJNZ PRINT; go on a cycle
RET; and return ...
The speed of this procedure is fairly small. If you get it,
ie, the speed is not satisfied, then it is time to return to
our screen fonts.
What do we have? Note
the design:
LD L, A
LD H, 0
ADD HL, HL
ADD HL, HL
ADD HL, HL
LD BC, FONT
ADD HL, BC
In this snippet code symbol is multiplied by eight and added
to the address of our font. This is, in fact, spans some of the
CPU time. If we are To be precise, the multiplication spends 33
clocks the symbol. It seems nonsense, but when printing,
For example, a screen, this minuscule result in a fair number
of cycles.
Due to the nature of constructing on-screen
fonts, to calculate the address of the symbol does not
to do multiplication. Ie, we now
save these 33 cycles, and in the print cycle
on the screen instead of INC HL, you need to do INC H,
which saves a further 16 cycles.
"Is it possible to more quickly," - asks the novice coder. Of
course you can. Look at this: first, what can be done,
especially not straining, as it is "unroll the loop." Ie, now
we do not have to be shipped in Register B "eight" (save 7
clocks), and accordingly, no need to do DJNZ, that
also saves a fair amount of clock cycles.
But note that code section, perebrasyvayushy bytes of the font
in the screen must be repeated eight times, and this leads to
an increase in the size of procedure. Should pay for
everything: (Oh, and do not Remember, if the transfer of the
last byte on the screen, remove unnecessary commands INC D and
INC H. Why waste time on them?
For the lazy cite the text of the expedited procedure. And
here it is;)
;===== Print character 8x8 (fast) =====
; In: DE - coordinates, A - character code
Pr_Sym LD L, A; in HL - code symbols
LD H, 0, la, we
LD BC, font; added to the
ADD HL, BC; start address font
LD A, D; familiar to us already
AND 7; protsedurka;)
RRCA
RRCA
RRCA
OR E
LD E, A
LD A, D
AND 24
OR 64
LD D, A
DUP 7; directive ALASM!!!
LD A, (HL); take a byte from the font
LD (DE), A; and put in a screen
INC H; increment fnt adr
INC D; increment scr adr
EDUP; and so 8 times
LD A, (HL)
LD (DE), A
RET; back ...
Print characters 4x8
To print characters of a given size is more convenient to use
a screen font, where each character is duplicated in the left
and the right side. Something like this:
adr: bin:
# C000 00000000
# C100 01000100
# C200 10101010
# C300 10101010
# C400 11101110
# C500 10101010
# C600 10101010
# C700 00000000
Why is it necessary - see below, in the course of
article.
What is so radically different from the print character 4x8
8x8 print character? One difference is that
Now for the X-coordinate, we can print
as much as 64 characters, and hence it is
coordinate, can be set from 0 to 63.
Next, we need to translate these coordinates in the form
acceptable to us, because at screen of 32 familiarity. In
general, I will not suffer this garbage and the same score
text. In short, Sklifosovsky!
Take the coordinate X, we shift its team
RR E (usually the X-coordinate marketing "sits"
it is here). Then we get the usual
for the 32-character print coordinates, and
carry flag will indicate which of the halves of familiarity
print.
Here is an example, unpretentious, but at the
However, it is a workable procedure to print the symbols of
this size.
;===========================
; Print driver symbols 4x8
; Print A at (D, E)
Print4 LD L, A
LD H, 0
LD BC, Font4
ADD HL, BC
RR E
JP C, RIGHT
CALL Posit
LD B, 8
LEFT LD A, (HL); print symbol on the left side
AND% 11110000
LD C, A
LD A, (DE)
OR C
LD (DE), A
INC D
INC H
DJNZ LEFT
RET
RIGHT CALL Posit; print symbol on the right side
LD B, 8
RIGHT1 LD A, (HL)
AND% 00001111
LD C, A
LD A, (DE)
OR C
LD (DE), A
INC H
INC D
DJNZ RIGHT1
RET
As you can see - nothing difficult!
Print characters 6x8
And there will have to tinker, because it
the most difficult to print a character matrix.
Immediately warn that there will be described only the
principle of printing such letters are not claiming to be
something special, because not the fastest speed. To
to learn how to quickly print such
fonts suggest you refer to other
magazines and newspapers, which are discussed in detail
these questions.
Cite the source immediately, and then prokomentiruem it all.
;===========================
; Print driver symbols 6x8
; Print A at (D, E)
Print68 EX DE, HL
PUSH HL
PUSH DE
PUSH BC
EX DE, HL; looking for the address of the symbol
LD L, A
LD H, 0
LD BC, Font6
ADD HL, BC
EX DE, HL; DE-char image
GetMasks LD A, L
LD B, A
SRL A
SRL A
LD C, A
ADC A, C
ADD A, C
LD L, A
; Procedure coords-> scr adres =
LD A, H
AND # 07
RRCA
RRCA
RRCA
ADD A, L
LD L, A
LD A, H
AND # 18
OR # 40
LD H, A; HL-screen addr
PUSH HL; depending on the X coordinate
LD A, B; take the appropriate mask for printing
AND # 03
ADD A, A
LD L, A
LD H, # 2000
LD BC, Masks
ADD HL, BC
LD C, (HL)
INC HL
LD B, (HL); BC-mask
POP HL
EXX
LD B, 8; BC = mask
PrtA1 EXX
LD A, (DE)
BIT 7, B
JR NZ, PrtA2
RRCA
RRCA
BIT 0, C
JR NZ, PrtA2
RRCA
RRCA
BIT 3, B
JR NZ, PrtA2
RRCA
RRCA
PrtA2 EXX
LD C, A
EXX
BIT 0, C
JR NZ, PrtA3
LD A, B
CPL
AND (HL)
LD (HL), A
EXX
LD A, C
EXX
AND B
OR (HL)
LD (HL), A
BIT 7, B
JR NZ, PrtA4
PrtA3 INC L
LD A, C
CPL
AND (HL)
LD (HL), A
EXX
LD A, C
EXX
AND C
OR (HL)
LD (HL), A
DEC L
PrtA4 INC H
INC D
EXX
DJNZ PrtA1
POP BC
POP DE
POP HL
RET
Masks DEFW # FC00; mask printing characters 6x8
DEFW # 03F0
DEFW # 0FC0
DEFW # 003F
When printing these fonts we already have to use things like
mask (what it is, I think, to explain
not necessary, because usually all programmers start out with a
print of sprites. And there close to the mask;) In general,
this procedure prints just two familiarity. It is necessary for
the reason that the width of a character by no means a multiple
of familiarity, it turns out that certain characters should be
print at the junction of the two familiarity. Interest also
lies in the fact that the 4-D symbol on occupy a width of
exactly three familiarity. Therefore, it is not difficult to
guess, only four masks. In fact, after every fourth characters
we are beginning to print from the beginning of familiarity,
etc.
At the start, depending on the coordinate
X, select the required mask and falls
on the screen, only then superimposed over the symbol. I think
that the principle is clear;)
You can print thong (messages) in portions at 4-D characters
each, ie multiple of familiarity. Thereby increasing the
printing speed. But we must use an another procedure;)
Print symbols in color
To do this we need to calculate the following address on the
screen to use this protsedurku, which translates the address in
the display area at the appropriate address in the field
attributes.
;========= Scr adr -> attr adr ========
; In: DE - screen adress
; Out: DE - attr adress
LD A, D
RRCA
RRCA
RRCA
AND 3
OR # 58
LD D, A
For symbols of 8x8 and 4x8, I think everything is
understandable, but to print 6x8 pomozgovat need to check on
how much familiarity must be painted - one or two. But this
I'll leave you to an independent study. Not all chew in his
mouth lozhit;) and must own a little thinking. And then we
shall everything here with atrophied like PTs'shnyh
gamers brains;)
Print strings
Finally give the sleek protsedurku
Print messages. Yes, the token installation
coordinates can be anything - it is already yours
case. You can add here and a token color settings: 16, a color
code. And it is possible as in ACEdit'e;)
;==================================
; -= The printing strings =; Rin: DE - coordinates
; HL - address of a string of text
Is supported by the tokens:
; 0 - End of Text
, 17, X, Y - coordinates printing plant
;==================================
Pr_Str LD A, (HL); take a character code
AND A; check for zero
RET Z; coincided - to leave
CP 17; check for token
JP NZ, Pr_Cont
INC HL; installation of the new coordinates
LD E, (HL)
INC HL
LD D, (HL)
INC HL
JP Pr_Str
Pr_Cont PUSH HL
PUSH DE
CALL Print8; you need it how to print
POP DE
POP HL
INC E
INC HL
JP Pr_Str