Assembler.
If you don't know what it is, but want to find out, then very
I recommend reading articles on this topic in ZF #7 & #8.
In this issue the material is already for those who understand, our main
3M coder will share his skills.
Hello people!
I (3M) decided to share some coding secrets on
SPECCY. I've been on the 'disk' SPECTRUM for only 2 years, before that
there was a home-made cassette LENINGRAD 48, which worked for 5 years and
died from my 'brilliant' modifications, + the GENS assembler package and
ZEUS with 'instant' delivery to cassette accompanied by mournful sounds
pilot signal. It was on him that I earned my professional bo-
The pain of all 48kb is minimalism. Now let's get down to business.
To begin with, I will give some procedures that I use for
writing your own programs. The first 2 of them are the most common and
the most necessary ones, calculate the address of the next line in
screen areas:
Input: HL - line address.
Output: HL - address of the next line.
Search for next Search for next
bottom line top line
NEXTHL INC H BACKHL DEC H
LD A,H LD A,H
AND 7 CPL
RET NZ AND 7
LD A,L RET NZ
ADD A,32 LD A,L
LD L,ASUB 32
RET C LD L,A
LD A,H RET C
SUB 8 LD A,H
LD H,A ADD A,8
RET LD H,A
RET
I hope there are no questions here? Let's move on. Next
The following procedure, also common, calculates the screen address
at known coordinates:
Input: H - Y (0-191), L - X (0-255).
Output: HL - address, B - bit number (0-7).
CORHL LD A,L
AND 7
LD B,A
XOR L
LD L,A
LD A,H
AND 7
LD C,A
XOR H
RRA
SCF
RRA
RRA
LD H,A
AND 7
OR L
RRCA
RRCA
RRCA
LD L,A
LD A,H
AND 248
OR C
LD H,A
RET
If you add to this procedure (before RET) the following lines:
INC B
LD A,1
ROLLER RRCA
DJNZ ROLLER
OR(HL) or XOR(HL); mask
LD(HL),A
then we get a procedure for printing a point - PLOT by coordinates in HL.
Although this procedure is very fast, its speed may not be
enough for temporary effects(DEMO, 3D graphics, etc.), for
They have a method for even faster point output in 69 clock cycles.
The following procedure was developed by me, oia prepares
sprite for printing with pixel accuracy (if anyone has the data)
This procedure works faster, please call).
Input: B - sprite height in pixels
C - sprite width in bytes
DE - sprite address
HL - buffer address
A - bit number or number of cyclic
sprite shifts (0-7)
Output: ready-made sprite with width+1 in the buffer
RUNSPR PUSH HL
EXX
LD (L13+1),A
INC A
LD B,A
LD A,1
L10 RRCA
DJNZ L10
LD E,A
DEC A
OR E
LD E,A
POP HL
EXX
L11 LD A,C
EXX
LD B,A
LD D,0
L12 EXX
LD A,(DE)
INC DE
L13 JR L13
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
EXX
LD C,A
AND E
ORD
LD(HL),A
INC HL
XOR D
XOR C
LD D,A
DJNZ L12
LD(HL),D
INC HL
EXX
DJNZ L11
RET
The uniqueness of this procedure is that it is 'free'
ret' sprites of any size.
Many novice coders are faced with the problem of printing
village. Her first clumsy solution is to use ROM routines,
who, as a result of close communication with the 'calculator', eat a lot
time. The following procedure will quickly prepare a number in the buffer in
in the form of a 5 byte string for its subsequent printing:
Input: HL - number (0-65535)
DE - 5 byte buffer address
Output: string of numbers in buffer
NUMSTR LD BC,10000
CALL L10
LD BC,1000
CALL L10
LD BC,100
CALL L10
LD BC,10
CALL L10
LD BC,1
L10 LD A,47
L11 INC A
SBC HL,BC
JR NC,L11
ADD HL,BC
LD(DE),A
INC DE
RET
The following procedure performs the reverse task of the previous one -
converts a string to a binary number:
Input: DE - 5 byte buffer address
Output: HL - number
STRNUM LD HL,0
LD BC,10000
CALL L10
LD BC,1000
CALL L10
LD BC,100
CALL L10
LD BC,10
CALL L10
LD BC,1
L10 LD A,(DE)
INC DE
L11 DEC A
C.P.47
RET Z
ADD HL,BC
JR L11
And now the procedure for multiplying a 2 byte number by 1 byte
(the idea is also mine):
Input: HL - number (0-65535)
A - number (0-255)
Output: HL=HL*A
HLA LD DE,0
HLA1 AND A
RET Z
RRA
JR NC,L10
EX DE,HL
ADD HL,DE
EX DE,HL
L10 ADD HL,HL
JR HLA1
If we run it with HLA1, it will be equivalent to calculating
HL=HL*A+DE.
And now 2 very short procedures for scrolling the screen by
familiar with the attributes:
SCROLL UP SCROLL DOWN
SCRUP LD DE,16384 SCRDW LD DE,23295
LD A,24 LD A,24
SU10 LD HL,32 SD10 LD HL,0-32
ADD HL,DE ADD HL,DE
LD BC,224 LD BC,224
LDIR LDDR
LD HL,1824 LD HL,0-1824
ADD HL,DE ADD HL,DE
LD BC,32 LD BC,32
LDIR LDDR
DEC A DEC A
JR NZ,SU10 JR NZ,SD10
RET RET
The issue of screen scrolling is very important for creating
niya full-fledged text VIEWERS. Since the non-turbocharged Z80
notmanages to refresh the screen in one interruption, then when scrolling
In many cases there is unreadable flickering of the text. For
In order to avoid this, it is necessary to synchronize scrolling with
interruptions and rapid screen restructuring. This can be achieved
using 2 128 SPECCY screens, or a method that has recently been used
came to my mind and which should show good results.
Its essence is that the finished screen begins to be thrown
not with the beginning of the interruption, but somewhere in the middle, as a result
which time for transfer will be about 1.5 INT, which on SCORPI-
ON'e (as on the brake one) will be >100,000 cycles, which is quite
not enough for scrolling without flickering. But all this is work -
Only when transferring (changing lanes) from top to bottom.
Sob may well provide scrolling speed without flickering
25 lines per second. And finally, I’ll give you the timing characteristics
some types of screen transfer (rearrangement):
TACT METHOD
1 according to LDIR 129024
2 procedures SCRUP,SCRDW 99696
3 stack throws 78336
This concludes this story.
I will be glad to listen to all responses, wishes, questions and suggestions
by phone 28-70-91 (Marat) from 20-22 h.
Share your thoughts about the article