|
ZX Forum #04
19 ноября 1997 |
|
New top 40 procedures - scrolling display, a fusion of two images, inverting screen, rotate characters, replacement of attributes, fill a closed loop, the calculation of addresses in the screen, copy of the screen, etc.

(C) Kolotov Sergei g.Shadrinsk,
SerzhSoft, July, 1997.
NEW "40 BEST PROCEDURES"
In 1992, on pages
ZX-REVIEW published an abridged translation of the book
Dzh.Hardmana and E. Hyuzon "top 40 procedures." The publication
has caused the most enthusiastic responses of readers
because many budding sinkleristy just use it to finally able to
overcome the difficulties "of the barrier machine code." But
here is exactly five years, and old-timers were surprised ZX
REVIEW notice in the first issue for 1997
year before the pain familiar name.
All the numerous arguments
so convincingly set forth INFORKOMOM, of course, largely
correct. But in my (and not
only my) opinion, they have
not entitle the national magazine publishers to spend precious
Page ZX-REVIEW print already
published at the time of the material.
Instead of heading a "retro" is much more useful and
relevant it would be enter the section "remake." And it
print is not just the old materials, and consider them more
deeply, to give examples more effective implementation
programs and other procedures.
Get at least the same "40 procedures." Yes, this work is very
useful for beginners. But
slightly more experienced experts assembler will notice that the
more on obemu reducible authors procedure to consistently
it has more disadvantages
more effectively implemented,
has more "extra" commands ... Yes, some
"Better procedures" are reduced
more than twice! And: Comments are
for by the listings, which is very
difficult to understand "what
it occurs when the procedure is executed at a certain
stage. "Of course, a description
Type "C register is copied into the register B", but here is
the semantic burden, which stands behind it,
understood is not always ...
It will be presented libraries, which integrates
graphic procedures, re-
copied on a "forty-best." The memory footprint was reduced from
1444 bytes to 861 bytes! Each procedure commented in detail in
the Listing her, so to speak - "is not
on the spot. "
Listing and hex dump.
Many of the procedures in their work requires some pre-
certain values - constants. Under these values are
allocated a special area of memory addressable Tagged CONSTS.
In this case CONSTS indicates address 23296, but, of course,
This address can be changed to any other. The length of the
constants of 8 bytes. If any of the procedures, none of the
constants does not change. Otherwise, would have to call them
variables ...
The procedures that manipulate
coordinates of points on the screen,
ostchet is in contrast to BASIC is not a bottom-up, and vice
versa - top-down. Such a reading of coordinates is much more
convenient and is used in many other computers. Now you can
specify Y coordinate from 0 to 191 (instead of
175), ie it is possible to specify the coordinates of the
dots on the screen that are in the bottom two rows to be
allocated under the error message. When counting the same
bottom-up maximum Y-coordinate is Y = 175, and to the lower of
the two lines do not reach.
BRIEF DESCRIPTION OF PROCEDURES
1. ASRL_LF - a procedure shifts the entire screen attributes
(color) to the left. The right column is filled with an
attribute of the cell to at CONSTS (23,296). Length
procedure, 22 bytes (was - 23
bytes). -Translated by the address 62000 (HEX: # F230).
2. ASRL_RG - translation of the whole
screen attributes to the right. Left
column filled with an attribute of
CONSTS. The length of the procedure, 21 bytes
(19 bytes). Located at 62022 (# F246).
3. ASRL_UP - translation of the whole
Screen attributes up. Bottom
string attribute is populated from
CONSTS. The length of the procedure, 19 bytes
(21 bytes). Address: 62043 (# F25B).
4. ASRL_DN - translation of the whole
Screen attributes down. Upper
attribute is to be filled out
CONSTS. Length: 20 bytes (21
bytes). Address: 62062 (# F26E).
5. SSRL_LF - translation of the whole
display left one character
(Graphics). The right column familiarity cleared. Length of 20
bytes (21 bytes). Address: 62082 (# F282).
6. SSRL_RG - translation of the whole
screen to the right by one character.
The left column familiarity cleared. Length of 19 bytes (22
bytes). Address: 62102 (# F296).
7. SSRL_UP - translation of the whole
the screen up one character.
The bottom line of familiarity is cleared. Length 55 bytes (68
bytes). Address: 62121 (# F2A9).
8. SSRL_DN - translation of the whole
screen down by one character.
The top line of familiarity is cleared. Length 55 bytes (73
bytes). Address: 62176 (# F2E0).
9. PSRL_LF - translation of the whole
to the left by one pixel
(Graphics). The right column of pixels is cleared. Length of 16
bytes (17 bytes). Address: 62231 (# F317).
10. PSRL_RG - translation of the whole
screen to the right by one pixel.
The left column of pixels is cleared. Length 17 bytes (17
bytes). Address: 62247 (# F327).
11. PSRL_UP - translation of the whole
the screen up one line of pixels. The bottom line of pixels
cleared. Length of 38 bytes (91
bytes). Address: 62264 (# F338).
12. PSRL_DN - translation of the whole
screen down one line of pixels. The top row of pixels
cleared. Length of 38 bytes (90
bytes). Address: 62302 (# F35E).
13. SCR_MRG - the merging of two
images (graphics, on the principle of
OR). Double-byte constant for
CONSTS address must contain
location, where the second picture in memory (overlay). The
result is put on the screen. The length of the procedure, 17
bytes (before - 21 bytes). Address of accommodation:
62,340 (# F384).
14. SCR_INV - invert
screen (graphics, on the principle of
NOT). All the pixels change their
meaning the opposite.
The length of the procedure, 12 bytes (was -
18 bytes). Address: 62357 (# F395).
15. SINV_UD - inverting the symbol vertically. Arrow
pointing upwards, is directed downward, and vice versa. In the
double-byte variable at CONSTS must contain the address of a
variable character. The length of the procedure, 20 bytes (so
was). Address allocation: 62,369 (# F3A1).
16. SINV_LR - inverting the symbol horizontally. Arrow
pointing left, is directed to the right, and vice versa. In the
double-byte variable at CONSTS must contain the address of a
variable character. The length of the procedure, 17 bytes (was
- 19 bytes). Address of accommodation: 62,389 (# F3B5).
17. SROTATE - rotate the character in a clockwise direction
at 90 degrees. In the double-byte variable at CONSTS must
contain the address of a variable character. Length of 26 bytes
(previously - 42 bytes). Address: 62406 (# F3C6).
18. ACHANGE - change the attributes of all symbols
screen. Bit operation. In
cell at CONSTS should
contain the mask bits: Bits that are set in a mask
remain in the attributes of the same, and
Bits that are masked are zero - would have zero value and the
attributes (operation AND (not "Y "!)). The cell at CONSTS +1
bytes must be included bits of which will be introduced in all
the attributes of the screen, ie, if this byte is a bit turned
on, it will be installed in all
attributes (OR operation). Length
procedure, 16 bytes (21 bytes). Address: 62432 (# F3E0).
19. AREPLC - search the attributes of a specific value and
replacing each found a new attribute value. In
cell at CONSTS should
contain a byte value to be replaced (that look). In
cell at CONSTS +1 must be the value of the substitute bytes
(the change). The length of the procedure, 18 bytes (22 bytes).
Address: 62448 (# F3F0).
20. PAINT - fill a specific area of the screen, bounded by
a line of pixels (fill). The starting point is given by putting
her on the X at CONSTS, and the coordinates of Y -
at CONSTS +1. If the Y coordinate greater than 191 or the point
at these coordinates is already installed, the program urgently
interrupted. This procedure does not
moveable due to procedure calls POINT. When shading is actively
uses the stack - it remembers the coordinates of the fill
lines. When painted over a large region of complex shape, it is
necessary and more space in RAM - between the end BASIC-program
and the address set by the operator CLEAR (The contents of the
system variable RAMTOP). If memory space is not
enough, it may crash.
The procedure takes 88 bytes, and
together with the procedure POINT - 123
bytes, which is more than twice
less than the length of procedure 1992
(263 bytes!) Address PAINT: 62,466
(# F402).
21. POINT - address calculation
point in the screen given the coordinates and status
this point (ON / OFF). Attention!
This procedure can only be used from native code
(Start of BASIC nothing
will). Before the call to
set in the register E coordinate X (0 .. 255), and in the case
D - coordinate Y (0 .. 191) tested the point. The output of the
procedure set in the register pair HL byte address on the
screen, which is the point, and in case C - the point in this
mask byte (one bit set in unit). Depending on whether
including the points or not, a flag is set zero: Z - a point not
included, NZ - point is included.
If the point is established (visible)
then register A (accumulator) is identical in meaning with the
register C, and if the point is not set, then A is reset.
Register B is always at the exit from the procedure is zero.
The length of the procedure, 35 bytes (the original took would
be about 70 bytes). Address allocation: 62554 (# F45A).
22. PFIGURE - construction of any pre-defined shapes
(Pattern) on the screen. Coordinates of the initial (starting)
points are given the same procedure PAINT. Template is given in
a string variable BASIC A $ (can change to any other, slightly
adjusting assembly listing or dump). A string of characters
has the following format (a little
differs from the original):
"5" - to reduce the X-coordinate
"6" - to increase the Y-coordinate
(The count goes from top to bottom)
"7" - to reduce the Y-coordinate
"8" - to increase the X-coordinate
"0" - put the point.
Any other characters are ignored. If the string variable
does not exist or does not contain any information, then the
program stops its work. Control the output of the initial
Ykoordinaty not, because part of the figure can still be seen.
Therefore, checking the output for
off-screen to put in myself
cycle of forming a pattern. Ability to 'wrap-round' is
preserved, ie still, when the output
X-coordinates for the left side of the screen, the pattern
appears to the right, and vice versa.
The procedure is not moveable.
Length PFIGURE: 98 bytes, and is used together with routine
POINT - 133 bytes, which is still much smaller than the
original (196 bytes). Address: 62589 (# F47D).
If the "open" procedure call
POINT, you PFIGURE be moved and will occupy about 125 bytes!
23. PSCALER - copy of the screen to another area of the
same screen with a possible increase up to X and / or Y.
Constants are used:
Address Name Comment
CONSTS X1_OLD one of the two initial X-coordinate pryamoug-ka
CONSTS +1 Y1_OLD one of the two initial Y-coordinate pryamoug-ka
CONSTS +2 X2_OLD one of the two initial X-coordinate pryamoug-ka
CONSTS +3 Y2_OLD one of the two initial Y-coordinate pryamoug-ka
CONSTS +4 XSCALE magnitude increase in X
CONSTS +5 YSCALE magnitude of increase in Y
CONSTS +6 X_NEW coordinates of the upper-left corner of the
screen, CONSTS +7 Y_NEW which is made up.
Coordinates of the initial rectangle for copy set in the
constants X1_OLD, Y1_OLD, X2_OLD, Y2_OLD, moreover, may
arranged in any order. The procedure itself will determine the
smallest and largest coordinates.
Emergency exit procedures
occurs in the following cases:
1. XSCALE = 0 - zoom scale
on X is zero
2. YSCALE = 0 - zoom scale
the Y equals zero
3. Y_NEW> 191 - the new coordinate
Y beyond the screen
4. Y1_OLD> 191 - the old coordinates
that Y1 beyond eq
wound
5. Y2_OLD> 191 - the old coordinates
Y2 that goes beyond the equivalence
wound.
Like the original, the program does not control that would
check the possibility of placing new picture on the screen. If
this does not work, you may
crash.
When performing the procedure at first throws a stack bit
image of the copied rectangle
screen and then draws it to the new location, increasing
if necessary. Therefore, if
on the stack is not enough space, then
As in the procedure PAINT, can occur hangs, reset,
Error ...
If you want to copy a piece of the screen had the
same size as a given, then
necessary to establish the scale of
1:1 - add a constant XSCALE
and YSCALE on yedinichku. When you double the amount there
should be dvoechki, and so on ...
The procedure is not moveable
from the use of sub POINT. PSCALER occupies 174
bytes, and with POINT - 209
bytes. In any case, it is much smaller than the original - 335
B! Address allocation: 62,687
(# F4DF).
So, here you are familiar with and
new implementation of the "better procedures". But I advise not
to have illusions - some of the procedures it should be
possible to reduce more ... True, this will inevitably have to
sacrifice something: the speed performance, transferability
and, finally, just the time spent. I hope that presented in
this paper the program will be useful, in extreme cases - may
be, they just touch up your thoughts on kakienibud ...
Beginners can try to compare the procedure in 1992 with new
study principles for creating more effective programs, tools
for the integration of many different procedures into one big
library ... Experienced programmers are the same, may get a lot
of fun, laughing mischievously over this work. But it is also
Plus: amuse people - very
the right thing! So I wish you all
readers to enjoy working with LOVED SPECCY!
140.
;-------------------------------------------------
-------------; , March 1940 New Best Routines (graphic);
3 (c) SerzhSoft, Shadrinsk, may-june, 1997;
; Old length: 1444 bytes new length: 861 bytes;
;-------------------------------------------------
-------------;
ORG 62000; address assembly
;-------------------------------------------------
-------------; CONSTS EQU 23296; buffer address constant (8
bytes) ;-------------------------------------------------
-------------; ; Shift attributes to the left (22 <= 23)
;-------------------------------------------------
-------------; ASRL_LF
LD DE, # 5800; DE = address of first byte of the
attribute LP_ASLF LD H, D; DE copied in HL
LD L, E; and HL increased by one:
INC HL; HL = address of the second byte of attributes
LD BC, # 001F; <line length attribute> - 1
LDIR; shift of the attributes of the left
LD A, (CONSTS); fill color after the shift
LD (DE), A; set a new attribute
INC DE; the transition to the next line below
LD A, D; if the attributes have already run out,
CP # 5B; and we came upon a printer buffer,
JR C, LP_ASLF; then STOP, otherwise continue to shift
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift attributes to the right (21 <= 23)
;-------------------------------------------------
-------------; ASRL_RG
LD DE, # 5AFF; address of the last byte of attributes
LP_ASRG LD H, D; DE copied in HL -
LD L, E; the last byte of the line attributes
DEC HL; the penultimate line of bytes of attributes
LD BC, # 001F; <line length attribute> - 1
LDDR; shift of the attributes of the right
LD A, (CONSTS); fill color after the shift
LD (DE), A; set a new attribute
DEC DE; the transition to the next line from the top
BIT 3, D; if we are still in the attributes,
JR NZ, LP_ASRG; then repeat the cycle for the lyrics.
line
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift attributes up (19 <= 21)
;-------------------------------------------------
-------------; ASRL_UP
LD HL, # 5820, and the address of second-line attributes
LD DE, # 5800; address of the first line of the
attributes
LD BC, # 02E0 3; move: 23 lines of 32 bytes
LDIR 3, shifting the bottom line up 23
LD A, (CONSTS); color to fill the bottom line
LP_ASUP LD (DE), A; set a new attribute
INC E; if you have filled the whole last line
JR NZ, LP_ASUP; (E = 0), interrupts the cycle
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift attributes down (20 <= 21)
;-------------------------------------------------
-------------; ASRL_DN
LD HL, # 5ADF; address of the end of the second line
below
LD DE, # 5AFF; address of the end of the bottom line
LD BC, # 02E0 3; move: 23 lines of 32 bytes
LDDR 3, shifting the line down the top 23
LD A, (CONSTS); color to fill the top line
LP_ASDN LD (DE), A; set a new attribute
DEC E; if you come down to the very first byte
JR NZ, LP_ASDN; field attributes (E = 0) then STOP
LD (DE), A; and set the byte
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift left one character (20 <= 21)
;-------------------------------------------------
-------------; SSRL_LF
LD DE, # 4000; top of graphics
LP_SSLF LD H, D; address of the first
LD L, E; byte line
INC HL; address of the second byte of the line
LD BC, # 001F; how many bytes to shift
LDIR; line shift to the left by 1 byte
XOR A; resets the battery and have brought
LD (DE), A; the last (right) bytes line
INC DE; the transition to the next line (below)
LD A, D; if the attributes
CP # 58; "not yet seen"
JR C, LP_SSLF; then repeat the cycle for the lyrics.
line
RET; exit procedures
;-------------------------------------------------
-------------; ; Right shift by one character (19 <= 22)
;-------------------------------------------------
-------------; SSRL_RG
LD DE, # 57FF; the last byte in the field of graphics
LP_SSRG LD H, D; address of the last byte
LD L, E; current line
DEC HL; address penultimate bytes
LD BC, # 001F 3; shift: 31 bytes
LDDR; shift of the line graphs to the right
XOR A; clear the battery and then
LD (DE), A; first (left) bytes of the current line
DEC DE; the transition to the next line above
BIT 6, D; if we did not "come across" on the ROM
JR NZ, LP_SSRG; then continue to twist the loop
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift up one character (55 <= 68)
;-------------------------------------------------
-------------; SSRL_UP
LD DE, # 4000; top display area
LP_SSU1 PUSH DE; stores the address line on the stack
LD BC, # 0020 3 line - 32 bytes
LD A, E; The register address is DE
ADD A, C; top line. The Register
LD L, A; HL to get the address
LD A, D; line lying below with step 8.
JR NC, GO_SSUP; For this sensitive E pribav
ADD A, # 3 August, trolled 32 and fills in L. If
proGO_SSUP LD H, A; emanated overflow, then H = D +8
LDIR 3; transfer line (32 bytes)
POP DE; restore the address of the start line
LD A, H; check: Is not it time we closed
CP # 58 3; glyatsya? (Transferred all 23 series)
JR NC, LP_SSU2; if so, the transition to clean
INC D ;---------------------------------;
LD A, D; DOWN_DE
AND # 07; standard sequence
JR NZ, LP_SSU1; teams to go on line
LD A, E; down in the display area
ADD A, # 20, (to register DE)
LD E, A;
JR C, LP_SSU1; input: DE - address line
LD A, D; output: DE - address line below
SUB # 08; battery is used
LD D, A;
JR LP_SSU1 ;---------------------------------;
LP_SSU2 XOR A; cleaning battery
LP_SSU3 LD (DE), A; and with his help -
INC E; cleaning of one line image
JR NZ, LP_SSU3 3 total: 32 bytes
LD E, # E0; move to the next
INC D; (lower) line image
BIT 3, D; filled the entire last series?
JR Z, LP_SSU2; if not, continue to fill
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift down by one character (55 <= 73)
;-------------------------------------------------
-------------; SSRL_DN
LD DE, # 57FF; address of the last byte of graphics
LP_SSD1 PUSH DE; store the address of the end of the line
LD BC, # 0020, the length of one line image
LD A, E; in register HL
SUB C; we address
LD L, A; end of the line
LD A, D; overlying
JR NC, GO_SSDN; initial steps
SUB # 08; of 8 pixels (lines):
GO_SSDN LD H, A; HL = from copy; DE = where
LDDR; transfer line graphs
POP DE; restore address the end of the line
BIT 6, H; if we are no longer in the screen,
JR Z, LP_SSD2; then go to clean up
LD A, D ;---------------------------------;
DEC D; UP_DE
AND # 07; standard sequence
JR NZ, LP_SSD1; teams to go on line
LD A, E; up in the display area
SUB # 20; (to register DE)
LD E, A;
JR C, LP_SSD1; input: DE - address line
LD A, D; output: DE - address line above
ADD A, # 08; battery is used
LD D, A;
JR LP_SSD1 ;---------------------------------;
LP_SSD2 XOR A; cleaning battery
LP_SSD3 LD (DE), A; cleaning of one
DEC E; image line:
JR NZ, LP_SSD3 3 (31 bytes)
LD (DE), A; clear the very first byte of the line
LD E, # 1F; move to the next (upper)
DEC D; through a number of the eight lines
BIT 6, D; we have not got the ROM?
JR NZ, LP_SSD2; if not, then clear the next
RET; exit procedures
;-------------------------------------------------
-------------; ; Left shift by one pixel (16 <= 17)
;-------------------------------------------------
-------------; PSRL_LF
LD HL, # 57FF; address of the last byte of graphics
LP_PSL1 OR A; reset the carry flag CF
LD B, # 20 March, in the same line - 32 bytes
LP_PSL2 RL (HL); CF <- [Sliding bytes] <-CF (left)
DEC HL; go to the previous byte line
DJNZ LP_PSL2; shift cycle for one line
BIT 6, H; we are still in the screen?
JR NZ, LP_PSL1; if so, shift the trail. line
RET; exit procedures
;-------------------------------------------------
-------------; ; Right shift by one pixel (17)
;-------------------------------------------------
-------------; PSRL_RG
LD HL, # 4000; address the first byte of graphics
LD C, # C0 3; shift - 192 lines
LP_PSR1 OR A; CF = 0 for an empty column on the left
LD B, # 20, the number of bytes in one line
LP_PSR2 RR (HL); shift one byte to the right
INC HL; next byte of image line
DJNZ LP_PSR2 3, we shift the whole line - 32 bytes
DEC C; decrease the counter lines
JR NZ, LP_PSR1; if you have moved all the lines, then
STOP
RET; exit procedures
;-------------------------------------------------
-------------; ; Upward shift by one pixel (38 <= 91)
;-------------------------------------------------
-------------; PSRL_UP
LD DE, # 4000; address of the beginning of graphics
(verh. line) LP_PSU1 LD H, D; copied the address of the
beginning
LD L, E; line graphs in HL
LD BC, # 0020, the size of a single line
INC H ;---------------------------------;
LD A, H; DOWN_HL
AND # 07; standard sequence
JR NZ, GO_PSUP; teams to go on line
LD A, L; down in the display area
ADD A, C; (for the register HL)
LD L, A; (here ADD A, C instead of ADD A, # 08)
JR C, GO_PSUP; Input: HL - address line
LD A, H; Output: HL - address line below
SUB # 08; battery is used
LD H, A ;---------------------------------;
GO_PSUP PUSH HL; store address the bottom line
LDIR; transfer images from the bottom-up
140. POP DE; DE - address the bottom line
LD A, H; we are still in the field of graphics
CP # 58; or have stumbled upon the attributes?
JR C, LP_PSU1; if still graphics, then repeat
XOR A; zero out the battery and its
LP_PSU2 LD (DE), A; help clear the most
INC E; bottom line of the image
JR NZ, LP_PSU2; after the shift the screen up
RET; exit procedures
;-------------------------------------------------
-------------; ; Shift down by one pixel (38 <= 90)
;-------------------------------------------------
-------------; PSRL_DN
LD DE, # 57FF; address of the last byte of graphics
LP_PSD1 LD H, D; copied the address of the last
LD L, E; byte line HL
LD BC, # 0020; width of one image line
LD A, H ;---------------------------------;
DEC H; UP_HL
AND # 07; standard sequence
JR NZ, GO_PSDN; teams to go on line
LD A, L; up in the display area
SUB C; (for the register HL)
LD L, A; (SUB C here instead SUB # 08)
JR C, GO_PSDN; Input: HL - address line
LD A, H; Output: HL - address line above
ADD A, # 08; battery is used
LD H, A ;---------------------------------;
GO_PSDN PUSH HL; store address the top line
LDDR; tolerated a line from the top - down
POP DE; address the top line has become the current
BIT 6, H; not yet got into the ROM -
JR NZ, LP_PSD1; continue the cycle of transmission lines
XOR A; clear the battery and its
LP_PSD2 LD (DE), A; help - the top-line
DEC E; image after the shift
JR NZ, LP_PSD2; the entire screen down
LD (DE), A; cleaning of the first byte
RET; exit procedures
;-------------------------------------------------
-------------; ; Merging the images (17 <= 21)
;-------------------------------------------------
-------------; SCR_MRG
LD HL, (CONSTS); URL for an image taken from a cell
LD DE, # 4000; address display area
LP_SCRM LD A, (DE); bytes screenshots
OR (HL); "leaked" to the byte image in memory
LD (DE), A; and placed back into the screen
INC HL; next byte images in the memory
INC DE; next byte of display area
LD A, D; checking for completion
CP # 58; display area
JR C, LP_SCRM; if not ended, then repeat
RET; exit procedures
;-------------------------------------------------
-------------; ; Inverting Screen (12 <= 18)
;-------------------------------------------------
-------------; SCR_INV
LD HL, # 57FF; last byte of the display area
LP_SCRI LD A, (HL); took bytes screenshots
CPL; proinvertirovali it
LD (HL), A; and put back
DEC HL; move to the top of
BIT 6, H; if "handled" through the origin,
JR NZ, LP_SCRI; then STOP, otherwise twist cycle
RET; exit procedures
;-------------------------------------------------
-------------; ; Inverting a vertical (20)
;-------------------------------------------------
-------------; SINV_UD
LD HL, (CONSTS); taken from the cell address of the
symbol
LD D, H; save this
LD E, L; address in DE
LD B, # 08; in the symbol - 8 bytes
LP_SIU1 LD A, (HL); take a one-byte characters
PUSH AF; and pushed on the stack
INC HL; the transition to the next byte characters
DJNZ LP_SIU1; repeat the cycle for the eight bytes
LD B, # 08; how many bytes will be read
LP_SIU2 POP AF; extract the bytes from the stack in reverse
LD (DE), A; Mr. procedure written in a symbol
INC DE; next byte characters
DJNZ LP_SIU2; twist cycle eight times
RET; exit procedures
;-------------------------------------------------
-------------; ; Inverting symbol horizontally (17 <= 19)
;-------------------------------------------------
-------------; SINV_LR
LD HL, (CONSTS); take out the cell address of the symbol
LD B, # 08; modify: 8 bytes
LP_SIL1 LD A, # 01; A set bit zero to 1
LP_SIL2 RR (HL); rotate byte characters left
RLA; and battery - to the left (via CF)
JR NC, LP_SIL2; until a zero bit will not appear in CF
LD (HL), A; write the modified byte
INC HL; next byte characters
DJNZ LP_SIL1; repeat cycle 8 times
RET; exit procedures
;-------------------------------------------------
-------------; ; Rotation of the symbol in a clockwise
direction (26 <= 42)
;-------------------------------------------------
-------------; SROTATE
LD HL, (CONSTS); address the rotating character of the
cell
LD B, # 08; 8 vertical columns in the symbol
LP_SRO1 PUSH HL; saved address on the stack
LD A, # 80, included the seventh bit in the accumulator
LP_SRO2 RR (HL); rotate the bytes of the symbol to the right
RRA; and one bit of each byte
INC HL; gradually fill the battery
JR NC, LP_SRO2; until 7 incl. bits do not fall into the
CF
POP HL; restore the address of the symbol
PUSH AF; satellite. column - character on the stack
DJNZ LP_SRO1; twist cycle by the number of columns
LD B, # 08; steel column lines - bytes
LP_SRO3 POP AF; pulls off bytes from the stack
LD (HL), A; and it is - has a new line character
INC HL; next byte characters
DJNZ LP_SRO3; repeat the number of lines (8 bytes)
RET; exit procedures
;-------------------------------------------------
-------------; ; Change the attribute (16 <= 21)
;-------------------------------------------------
-------------; ACHANGE
LD HL, (CONSTS); L - mask (AND), H - additive (OR)
LD DE, # 5AFF; the last byte of attributes
LP_ACHN LD A, (DE); take the current value of the attribute
AND L; threw extra bits
OR H; added the necessary
LD (DE), A; and recorded in the old place
DEC DE; move to the top attributes
BIT 3, D; and not a schedule already?
JR NZ, LP_ACHN; if not, then twist cycle
RET; exit procedures
;-------------------------------------------------
-------------; ; Change attribute (18 <= 22)
;-------------------------------------------------
-------------; AREPLC
LD DE, (CONSTS); E - what to look for, D - than to
replace
LD HL, # 5AFF; the last byte of attributes
LP_ARPL LD A, (HL); take a byte from the field attributes
CP E; Is not that looking for?
JR NZ, GO_ARPL; not jump change
LD (HL), D; yes, change to a new value
GO_ARPL DEC HL; move to the top region Tee attributes
BIT 3, H; attributes have not yet come to an end?
JR NZ, LP_ARPL; if not, then check the next
RET; exit procedures
;-------------------------------------------------
-------------; ; Paint circuit (123 <= 263)
, 123 = 88 +35 - together with the procedure POINT
;-------------------------------------------------
-------------; PAINT
LD HL, (CONSTS); coordinates of the starting point
LD A, H; check the Y coordinate for output
CP # C0; beyond the screen:
RET NC; if Y> = 192, then the extra output
SBC A, A; because CF = 1, then SBC A, A gives A = # FF -
PUSH AF; this will be the end of the stack pointer
PUSH HL; remember the coordinates of first point
LP_PNT1 POP DE; take from the stack X, Y et seq. point
INC D; if Y = # FF, then the stack is exhausted,
RET Z; and then exit the procedure
DEC D; restores. Y value
CALL POINT; check point with coord-mi (E, D)
JR NZ, LP_PNT1; if enabled, the transition to the next.
EX AF, AF '; A' = 0, CF = 0 - aux. signs
LP_PNT2 LD A, E; took the X coordinate
OR A; if it is zero,
JR Z, GO_PNT1; then jump through the backward movement
DEC E; differently - reduce the X coordinate
CALL POINT; and check the previous point
JR Z, LP_PNT2; if "no obstacle", repeat
LP_PNT3 INC E; the transition to point to the right (X = X +1)
JR Z, LP_PNT1; if X> 255, ff. point from the stack
GO_PNT1 CALL POINT; check the following right point
JR NZ, LP_PNT1; if enabled, the trace. from the stack
LD A, (HL); if the point is not established,
OR C; then take a byte from the screen, turn on
LD (HL), A; the right bits and put back
LD A, D; check coordinate Y:
OR A; if it is zero,
JR Z, GO_PNT4; do not check the lying. above the line
DEC D; the transition to the line above (Y = Y-1)
CALL POINT; test points overlying
JR Z, GO_PNT2; if not included, the transition
EX AF, AF '; have auxiliary flags
LD A, B; allowed to memorize a point in the stack
JR GO_PNT3; the transition to the continuation of
GO_PNT2 EX AF, AF '; have auxiliary flags
INC A; if A> 0, it means a ban
DEC A; to save the new coordinates
JR NZ, GO_PNT3; point in the stack -> jump
LD A, C; otherwise - do not store the coordinates
PUSH DE; coordinates, but one shoves a stack
GO_PNT3 EX AF, AF '; retained support flags
INC D; return to the bottom line
GO_PNT4 LD A, D; check coordinate Y:
CP # BF; if - the latter (below do not happen)
JR NC, LP_PNT3; the transition to the next. point to
the right
INC D; otherwise - get down on the line below
CALL POINT; check the underlying point
JR Z, GO_PNT5; if not included, the transition
EX AF, AF '; have auxiliary flags
AND A; allowed to memorize a point in the stack
JR GO_PNT6; the transition to the continuation of
GO_PNT5 EX AF, AF '; have auxiliary flags
JR C, GO_PNT6; if you can not save, then go
SCF; forbid save point on the stack
PUSH DE; but one point on the stack pushes
GO_PNT6 EX AF, AF '; retained support flags
DEC D; return to the top of the line
JR LP_PNT3; the transition to the next point on the
right ;-------------------------------------------------
-------------; ; Check the status of the point and the
calculation of addresses in the screen (35 <= 70)
;-------------------------------------------------
-------------; POINT; if the point is disabled, ZF = 1 (Z),
otherwise, ZF = 0 (NZ)
LD B, # 07; commonly used mask (# 07)
LD A, D; took the Y-coordinate
RRA; divided it into 8
SCF; and began to form
RRA; byte
RRA; address of the pixel
AND # 5F; in the screen (register H):
LD H, A;% 010yyyyy
XOR E; then form the
AND B; low byte
XOR E; address
RRCA; pixel
RRCA; in the screen
RRCA; (case L):
LD L, A;% yyyxxxxx
LD A, D; finish
XOR H; formation
AND B; High Byte
XOR H; address of the pixel
LD H, A; in the screen (register H)
140. LD A, E; begin forming
AND B; mask pixel in a byte
LD B, A; image (corresponding
LD A, # 80; bit included). Turn on the seventh bit
JR Z, GO_PNT; if this is just what is necessary,
LP_PNT RRCA; then jump through a shift
DJNZ LP_PNT; included bits to the right
GO_PNT LD C, A; save mask inc. bit in the reg. C
AND (HL); check the pixel in the screen
RET; exit procedures
;-------------------------------------------------
-------------; ; Building templates (98 <= 196)
; 98 35 = 133 - together with the procedure POINT
;-------------------------------------------------
-------------; PFIGURE
LD DE, (CONSTS); coordinates of the starting point
LD HL, (23627), the start address of the variables BASIC
LP_PFG1 LD A, (HL); the first byte of a variable
INC HL; the transition to the next byte
LD BC, # 0012, the size of the loop variable FOR ...
NEXT
CP # E0; found a loop variable FOR ... NEXT?
JR NC, GO_PFG2; if yes, go to the next. Vac.
CP # 80; BASIC variables over?
RET Z; if so, exit procedures
LD C, # 05; long numbers. Vac. single characters.
JR NC, GO_PFG3; array or a number. per. with several.
Sim.
CP # 60, the number of changes. single characters. in a
name?
JR NC, GO_PFG2; yes, go to the next variable
CP "A"; the name of a character variable (A $)
JR Z, GO_PFG4; cheers, still found and and and and!
GO_PFG1 LD C, (HL); obtain
INC HL; the size of the study
LD B, (HL); variable
INC HL; in bytes, and
GO_PFG2 ADD HL, BC; adding to the address
JR LP_PFG1; proceed to the next variable
GO_PFG3 BIT 5, A; array variable?
JR Z, GO_PFG1; yes, jump over it
LP_PFG2 BIT 7, (HL); check at the end it is the number. per.
INC HL; next byte name
JR NZ, GO_PFG1; name has ended, the transition
JR LP_PFG2; continue to see the name
GO_PFG4 LD C, (HL); have long found
INC HL; string variable
LD B, (HL); with data on the pattern
LP_PFG3 INC HL; next character template data
LD A, B; check: Do not run out
OR C; we all data on the pattern?
RET Z; if so (length = 0) then exit
DEC BC; reduced the length of
LD A, (HL); took the character template data
CP "0" and not "put a point?
JR NZ, GO_PFG6; if not, go to the continuation of
LD A, D; y-coordinate of current point
CP # C0; if the outside bottom edge of the
JR NC, LP_PFG3; screen, the point does not represent
PUSH HL; otherwise - keep some
PUSH BC; registers, not to spoil
CALL POINT; call validation points
LD A, (HL); on the calculated values
OR C; image point on the screen
LD (HL), A; using the fact that HL = address
POP BC; and C register contains a mask point
POP HL; restore the preserved-nye registers
JR LP_PFG3; processing trace. wildcard
GO_PFG6 SUB "5" to shift the pen to the left?
JR NZ, GO_PFG7; if not, leave it as is
DEC E; otherwise - to reduce the x-coordinate
GO_PFG7 DEC A; move down?
JR NZ, GO_PFG8; no transition
INC D; yes, we increase the y-coordinate
GO_PFG8 DEC A; direction "up"?
JR NZ, GO_PFG9; not jump
DEC D; yes, reduce the y-coordinate
GO_PFG9 DEC A; may need to move to the right?
JR NZ, LP_PFG3; not, go to the next. character of
Chablis.
INC E; yes, we increase the x-coordinate
JR LP_PFG3; and proceed to the next. character of
Chablis. ;-------------------------------------------------
-------------; ; Increase the screen and up (174 <= 335)
; 174 35 = 209 - together with the procedure POINT
;-------------------------------------------------
-------------; PSCALER
LD HL, (CONSTS +4); magnitude of increase in x and y
INC L; checking x-coordinate
DEC L; to zero
RET Z; if equal to 0, the error (output)
INC H; checking the y-coordinate
DEC H; to zero
RET Z; if equal to 0, the error (output)
LD HL, (CONSTS +6); new x-, y-coordinate ("where")
LD A, # BF; maximum possible y-coordinate
CP H; check the new y-coordinate
RET C; if not at the screen - Output
LD HL, (CONSTS); x1-, y1-coordinate ("source")
CP H; check y1 by entering the screen
RET C; if behind a screen, then exit
LD DE, (CONSTS +2); x2-, y2-coordinate ("source")
CP D; y2 is the screen?
RET C; if not, exit procedures
LD A, E; coordinate x2
CP L; compared with the coordinate x1
JR NC, GO_PSC1; if L <E, then everything is fine
EX DE, HL; otherwise - have changed their places
GO_PSC1 LD A, D; coordinate y2
CP H; compared with the coordinate y1
JR NC, GO_PSC2; if H 0, the CF flag turned on
RR B; "twist" this bit in the register B
DEC C; decrements the number of bits
JR NZ, GO_PSC3; if not zero, then jump
PUSH BC; else - throws a stack
INC SP; register B (only 1 byte)
LD C, # 08; and set the counter bits
GO_PSC3 LD A, E; current x-coordinate
DEC E; moving through the left
CP L; check on end line
JR NZ, LP_PSC2; twist cycle through
EX AF, AF '; recover the value of
LD E, A; x-coordinate of the alternative A
LD A, D; current y-coordinate
DEC D;'re going to line up
CP H; it was the last line?
JR NZ, LP_PSC1; if not, then we turn loop on lines
LD A, # 08; the number of bits in a byte
SUB C; A = number of occupied bits in reg. B
JR NZ, GO_PSC4; if not zero, then jump
LD A, C; A = C = 8 - number of bits in a byte
DEC SP; remove from the stack the last
POP BC; abandoned there Bytes
GO_PSC4 LD C, A; how many bits of data seq. byte
LD DE, (CONSTS +6); new x-, y-coordinate ("where")
LP_PSC3 LD A, E; store x-coordinate of the start
EX AF, AF '; line image A'
EXX; transition to alternative registries
LD E, C; it will count for points x
LP_PSC4 EXX; back to Main. register set
EX AF, AF '; transition to Alt. flag. Register
RLC B; flag CF - print / ne_vyv. point
EX AF, AF '; returned to normal flags
PUSH BC; store bytes of data and Acc. bits
LD HL, (CONSTS +4); magnitude of increase in x and y
LD B, H; kept the magnitude of increases
LD C, L; in registers C and B (x and y)
PUSH DE; keep you coordinates (the loop on lines)
LP_PSC5 PUSH DE; store coordinates you (the cycle on points)
LP_PSC6 PUSH HL; save registers HL and BC
PUSH BC; before calling the procedure POINT
CALL POINT; calculation of addresses in the screen and
mask
LD A, C; mask points (bit included)
POP BC; BC restored from the stack
EX AF, AF '; check alternate CF flag
JR C, GO_PSC5; if it is enabled, then jump
EX AF, AF '; keep this flag CF
CPL; invert the mask bits point
AND (HL); and use it to reset the pixel
JR GO_PSC6; the transition to the continuation of
GO_PSC5 EX AF, AF '; CF flag again make alternative nym
OR (HL); include pixel
GO_PSC6 LD (HL), A; write bytes changed in the screen
POP HL; restore HL (sch. scale)
INC E; the transition to the lyrics. point in the line
of the screen
DEC L; decrements the scale of x
JR NZ, LP_PSC6; is not zero, continue to cycle
LD L, C; recover the value of x-scale.
POP DE; Restore, it coordinates the start line
INC D; the transition to the next line in the screen
DEC H; decrements the scale of y
JR NZ, LP_PSC5; and steep until it reaches 0
LD H, B; recover the value of y-scale.
POP DE; Restore, it coordinates the start point
LD A, E; the transition to the beginning of the next
ADD A, L; rectangle depicting
LD E, A; one point of the image (right)
POP BC; restore the byte to Dr. X and the counter
DEC C; decrements of bits in a byte B
JR NZ, GO_PSC7; if there are bits, then the transition
DEC SP; otherwise - are read from the stack
POP BC; next byte of data in the register B
LD C, # 08; set the counter bits
GO_PSC7 EXX; transition to alternative registries
DEC E; decrements points in a row
JR NZ, LP_PSC4; if you still have a point, then run
around
EXX; back to Main. register set
EX AF, AF '; restore from an alternate
LD E, A; battery x-coordinate lines
LD A, D; the transition to the beginning of the next
straight ADD A, H; gon, depicts one
LD D, A; point of the image (down)
EXX; transition to alternative registries
DEC B; reduce the row count sprite
EXX; back to Main. register set
JR NZ, LP_PSC3; cycle if the line did not end
RET; exit procedures
;-------------------------------------------------
-------------; 3; end of 1940 New Best Routines (graphic);
;-------------------------------------------------
-------------; 2
Hex dump of the library
F270: 5A 11 FF 5A 01 02 E0 ED: F6
F278: B8 3A 00 5B 12 1D 20 FC: 02
F280: C9 12 November 2000 40 62 6B 23: 8E
F288: 01 1F 00 ED B0 AF 13 December: 0B
F290: 7A FE 58 38 F0 C9 11 FF: 53
F298: 57 62 6B 2B 01 1F 00 ED: E6
F2A0: B8 AF 12 1B CB 72 20 F1: 74
F2A8: C9 D5 40 November 2000 20 January 2000: AA
F2B0: 7B 81 6F 7A C6 30 February 2008: 87
F2B8: 67 ED B0 D1 7C FE 58 30: 81
F2C0: December 14 7A E6 July 20 E5 7B: BF
F2C8: C6 20 5F 38 DF 7A D6 08: 6E
F2D0: 57 18 D9 AF 12 1C 20 FC: 03
F2D8: 1E E0 14 CB 5A 28 F4 C9: E6
F2E0: 11 FF 57 D5 20 January 2000 7B: AA
F2E8: 91 6F 7A 30 February D6 August 1967: CB
F2F0: ED B8 D1 CB 74 December 28 7A: 4B
F2F8: 15 July 1920 E6 E6 7B D6 20: 63
F300: 5F 38 E0 7A C6 18 August 1957: 21
F308: DA AF 12 1D 20 12 FC 1E: FF
F310: 1F CB 15 72 20 F3 C9 21: 71
F318: FF 57 B7 CB 20 June 1916 2B: 4A
F320: 10 FB CB 74 20 21 F4 C9: 5B
F328: 00 40 0E C0 B7 20 June CB: D1
F330: 1E 23 October FB 0D 20 F5 C9: 5A
F338: November 2000 40 62 6B 20 January 2000: 6A
F340: 24 7C E6 20 July 2009 7D 81: E7
F348: 6F 38 04 7C D6 August 1967 E5: 8C
F350: ED B0 D1 7C FE 58 38 E3: 9E
F358: AF 12 1C 20 FC C9 11 FF: 1D
F360: 57 62 6B 20 January 2000 7C 25: 39
F368: E6 20 July 2009 7D 91 6F 38: 26
F370: 04 7C C6 August 1967 E5 ED B8: A2
F378: D1 CB 74 20 E4 AF 12 1D: 5D
F380: 20 FC 12 C9 2A 00 5B 11: 00
F388: 00 40 1A B6 23 December 1913 7A: 4D
F390: FE 58 38 F6 C9 21 FF 57: 47
F398: 7E 2F 77 2B CB 74 20 F8: 31
F3A0: C9 2A 00 5B 5D 54 June 2008: A0
F3A8: 7E F5 Oct. 23 FB June 2008 F1: 3B
F3B0: 13 December 1910 FB C9 2A 00 5B: 21
F3B8: June 2008 3E 01 CB 1E 17 30: 28
F3C0: FB 1977 October 23 F5 C9 2A 00: 40
F3C8: 5B June 2008 E5 3E 80 CB 1E: B0
F3D0: 1F 23 30 FA E1 F5 10 F3: 08
F3D8: June 2008 F1 1977 Oct. 23 FB C9: 38
F3E0: 2A 00 5B 11 FF 5A 1A A5: 81
F3E8: B4 12 1B CB 5A 20 F7 C9: C1
F3F0: ED 5B 00 5B 21 FF 5A 7E: 7E
F3F8: BB 20 January 1972 2B CB 5C 20: AB
F400: F6 C9 2A 00 5B 7C FE C0: 72
F408: D0 9F F5 E5 D1 14 15 C8: 07
F410: CD 5A F4 20 F7 08 7B B7: 70
F418: 28 September 1D CD 5A F4 28 F6: 1993
F420: 1C 28 E9 CD 5A F4 20 E4: 60
F428: 7E B1 77 7A B7 28 13 15: 43
F430: CD 5A F4 28 April 2008 78 18: 03
F438: July 2008 3C 3D 20 February 1979 D5: 24
F440: August 14 7A FE BF 30 D9 14: A4
F448: CD 5A F4 28 April 2008 A7 1918: 4A
F450: Aug. 5, 1938 February 1937 August 1915 D5: B4
F458: 18 June 2007 C6 7A 1F 37 1F: 26
F460: 1F E6 5F 67 AB A0 AB 0F: 24
F468: 0F 0F 6F 7A AC A0 AC 67: C2
F470: 7B A0 47 3E 80 28 03 0F: BE
F478: 10 FD 4F A6 C9 ED 5B 00: 7F
F480: 5B 2A 4B 5C 7E 23 January 1912: 54
F488: 00 FE E0 30 13 FE 80 C8: E3
F490: 0E May 30 0F FE 60 August 30: 6C
F498: FE 41 28 12 4E 23 46 23: DF
F4A0: September 18 E1 CB 6F 1928 F5 CB: B8
F4A8: 7E 23 20 F0 18 23 F9 4E: CF
F4B0: 46 23 78 B1 C8 0B 7E FE: 85
F4B8: 1930 November 20 7A FE C0 30 F1: 66
F4C0: E5 C5 CD 5A F4 7E B1 77: 1F
F4C8: C1 E1 18 E5 D6 35 20 01: 87
F4D0: 1D 3D 3D 20 January 1914 20 January: B1
F4D8: 15 3D 20 D5 1C 18 D2 2A: 43
F4E0: 04 5B 2C 2D C8 24 25 C8: 65
F4E8: 2A 06 5B 3E BF BC D8 2A: 22
F4F0: 00 5B BC D8 ED 5B 02 5B: 78
F4F8: BA D8 7B BD January 30 EB 7A: 4C
F500: BC February 30, 1954 1967 7A 94 3C: E8
F508: D9 47 D9 7B 95 3C D9 4F: 6A
F510: D9 F5 33 0E 08 7B 08 E5: 84
F518: C5 CD 5A F4 C1 E1 C6 FF: 54
F520: CB 18 0D April 20 C5 33 0E: 2F
F528: 08 7B 1D BD 20 E9 08 5F: EA
F530: 7A 15 BC 20 E0 3E August 1991: 47
F538: 20 March 1979 3B C1 4F ED 5B: 5C
F540: 06 5B 7B 08 D9 59 D9 08: 2C
F548: CB 00 08 C5 2A 04 5B 44: A2
F550: 4D D5 D5 E5 C5 CD 5A F4: 01
F558: C1 1979 August 1938 May 2008 2F A6: A9
F560: 18 February 2008 B6 77 E1 1C 2D: CE
F568: 20 E9 69 D1 14 25 20 E2: DB
F570: 60 D1 7B 85 5F C1 0D 20: E3
F578: 04 3B C1 0E 08 D9 1D 20: 99
F580: C5 D9 08 5F 7A 84 57 D9: A8
F588: 05 D9 20 B6 C9 00 00 00: FA
Saving: SAVE "nbestg.c" CODE 62000,861
*
Other articles:
Similar articles:
В этот день... 29 October