╔═══════════════════════════════════════╗
| Coding... |
╚═══════════════════════════════════════╝
Emloyer/Alliance
2:5O8O/141.16
Dmitry Krylov
subj: то Employer
Вступление
----------
На сегодня создано достаточно программ,
а в частности демух, с использованием
3D renderinga в реальном времени. В этой
статье я попытаюсь рассказать, о том
как максимально (!?) быстро обсчитать
трехмерное пространство. Я буду считать,
что вы знаете как представляется в прос-
транстве 3D обьекты, линии, грани, точки
и т.д. Расскажу лишь о том какquickly
perform these calculations with examples on as-
assembler.
First, a few procedures on Asme:
Print dots
------------
To construct a point, you need a procedure
converting coordinates to screen address
The INFORCOM procedure is too slow.
My procedure requires 1kb to work
memory. I will also note that the procedure
INFORCOM eats xxx cycles, and mine
76-8O cycles. Here are 2 (two)
procedures (76.8O cycles).
For a procedure of 8O clock cycles in register B, C
X,Y coordinates must be specified, and
for 76 bars in C,L.
The installer for both procedures is the same
therefore, he comes first, and then, PLOT.
: Install
INST
LD HL,#62OO: Table address
LD В,4
LO1I PUSH Sun
XOR A
LD V,8LO2I PUSH Sun
LD V,8
LOЗI LD (HL),A
INC HL
DJNZ LOЗI
ADD A,#2O
POP sun
DJNZ LO2I
POP BC
DJNZ LO1I
LD A,#4O : Segment address
LD B,3: for printing
LOCHI PUSH Sun
LD V,8
LOSI PUSH VS,AF
LD V,8
LObI LD (HL),A
INC HL
INC A
DJNZ LObI
POP AF,SUN
DJNZ LOSI
ADD A,8
POP sun
DJNZ LOCHI
LD D,H
LD E,L
INC DE
LD BC,63
XOR A
LD(HL),ALDIR
INC HL
LD В,#2O
LO7I PUSH ВС
LD В,8
LO8I LD (HL),A
INC HL
DJNZ LO8I
INC A
POP ВС
DJNZ LO7I
LD A,#8O
LD В,#2O
LO9I PUSH ВС,AF
LD В,8
LOAI LD (HL),A
SRL A
INC HL
DJNZ LOAI
POP AF,ВС
DJNZ LO9I
RET
: FAST PLOT 8O takts
LD ВС,#OOOO
CALL PLOT
RET
PLOT LD H,#62: 7
LD L,В: 4
LD A,(HL): 7
INC H: 4
LD D,(HL): 7INC H: 4
LD L,C: 4
ADD A,(HL): 7
LD E,A: 4
INC H: 4
LD A,(DE): 7
OR (HL): 7
LD (DE),A: 7
RET
: FAST PLOT 76 takts
LD C,O: OR (HL): 7
LD (DE),A: 7
RET
Построение линии ----------------
bc x1y1
of x2y2
LINE LD A,H
SUB D
JR NC,LINE1
EX DE,HL
NEG
LINE1 LD H,A
LD A,L
SUB E
JR NC,LINER
NEG
СР H
LD L,A
JR C,LINELU
PUSH HL
CALL GET_ADR
POP OF
LD В,E
LD A,E
INC D
INC В
EX AF,AF
LINELD1 LD A,(HL)
OR C
LD (HL),A
RLC C
JP NC,LINELD2
DEC L
LINELD2EX AF,AF
SUB D
JR NC,LINELDЧ
ADD A,E
EX AF,AF
LD A,H
DEC H
AND 7
JP NZ,LINELDЗ
LD A,L
SUB #2O
LD L,A
JR C,LINELDЗ
LD A,H
ADD A,8
LD H,A
LINELDЗ DJNZ LINELD1
RET
LINELDЧ EX AF,AF
DJNZ LINELD1
RET
LINELU PUSH HL
CALL GET_ADR
POP DE
LD В,D
LD A,D
INC E
INC В
EX AF,AF
LINELU1 LD A,(HL)
OR C
LD (HL),ALD A,H
DEC H
AND 7
JP NZ,LINELU2
LD A,L
SUB #2O
LD L,A
JR C,LINELU2
LD A,H
ADD A,8
LD H,A
LINELU2 EX AF,AF
SUB E
JR NC,LINELUZ
ADD A,D
RLC C
JP NC,LINELUZ
DEC L
LINELUZ EX AF,AF
DJNZ LINELU1
RET
LINER SR H
LD L,A
JR C,LINERU
PUSH HL
CALL GET_ADR
POP DE
LD B,E
LD A,E
INC D
INC B
EX AF,AF
LINERD1 LD A,(HL)
OR C
LD (HL),A
RRC C
JP NC,LINERD2
INC L
LINERD2 EX AF,AF
SUB D
JR NC,LINERDЧ
ADD A,E
EX AF,AF
LD A,H
DEC H
AND 7
JP NZ,LINERDЗ
LD A,L
SUB #2O
LD L,A
JR C,LINERDЗ
LD A,H
ADD A,8
LD H,A
LINERDЗ DJNZ LINERD1
RET
LINERDЧ EX AF,AF
DJNZ LINERD1
RET
LINERU PUSH HL
CALL GET_ADR
POP DE
LD В,DLD A,D
INC E
INC В
EX AF,AF
LINERU1 LD A,(HL)
OR C
LD (HL),A
LD A,H
DEC H
AND 7
JP NZ,LINERU2
LD A,L
SUB #2O
LD L,A
JR C,LINERU2
LD A,H
ADD A,8
LD H,A
LINERU2 EX AF,AF
SUB E
JR NC,LINERUЗ
ADD A,D
RRC C
JP NC,LINERUЗ
INC L
LINERUЗ EX AF,AF
DJNZ LINERU1
RET
GET_ADR LD A,#BF
SUB D
LD D,ASRL A
SCF
RRA
SRL A
XOR D
AND #F8
XOR D
LD H,A
LD A,E
RLCA
RLCA
RLCA
XOR D
AND #C7
XOR D
RLCA
RLCA
LD L,A
LD A,E
AND 7
INC A
LD C,В
LD В,A
LD A,1
GETADR1 RRCA
DJNZ GETADR1
LD В,C
LD C,A
RET Multiplication/division
-----------------
You will have to multiply at every step because
3D graphics are, as you know, solid
mathematics.
In registers A,B there are multipliers
You will receive the result in the A/HL register
MUL_AB PUSH DE,HL
LD C,A
LD A,127
SR C
JR NC,N2
SR B
JR NC,N21
PUSH Sun
LD A,B
N.E.G.
LD B,A
LD A,C
N.E.G.
CALL MUL
POP sun
ADD HL,HL
LD A,H
JP OK
N21 LD A,C
N.E.G.
CALL MUL
ADD HL,HLXOR A
SUB L
LD L,A
LD A,O
SBC A,H
LD H,A
JP OK
N2 СР В
JR NC,N22
PUSH ВС
LD A,В
NEG
LD В,A
LD A,C
CALL MUL
POP ВС
ADD HL,HL
XOR A
SUB L
LD L,A
LD A,O
SBC A,H
LD H,A
JP OK
N22 LD A,C
CALL MUL
ADD HL,HL
LD A,H
OK POP HL,DE
RET
MUL LD D,O
LD E,ВLD HL,O
RLA
JP NC,М1
ADD HL,DE
М1 ADD HL,HL
RLA
JP NC,М2
ADD HL,DE
М2 ADD HL,HL
RLA
JP NC,М3
ADD HL,DE
М3 ADD HL,HL
RLA
JP NC,М4
ADD HL,DE
М4 ADD HL,HL
RLA
JP NC,М5
ADD HL,DE
М5 ADD HL,HL
RLA
JP NC,М6
ADD HL,DE
М6 ADD HL,HL
RLA
JP NC,М7
ADD HL,DE
М7 ADD HL,HL
RLA
RET NC
ADDHL,DE
RET
This program works quite quickly
because it was written not by anyone but by himself
Sergey Kovinov, but it’s still possible
faster. And in a faster way I will
I'll tell you later.
Speaking of division:
According to the author of this procedure, she
can only multiply, but I noticed
one feature. If you multiply the coordinates
natu on numbers from 128 to 255, then they
will be divisible by numbers from 1 to 127
Using this, for example, you can scale
capture a 3D object.
SIN (x), COS (x)
----------------
Because SPECCY has no math
coprocessor to implement these functions
It is possible only programmatically, i.e. on Asm'e
And this can be implemented in three ways.
1. expansion of functions in Fourier series.
2. use the built-in calculator.
3. calculate the table in advance.
The first method will lead to a fatal accident.
capabilities comparable to BASIC.
Method 2 will not improve performance
because the built-in calculator is also laid out
puts these functions into a Fourier series.By the way, BASIC actively uses this
the most calculator.
The last method is preferable because
You won’t have to count SIN and COS.
Values are already ready for all angles.
Because SIN and COS values are in the range
not from O to 1 they will have to be multiplied by
the amplitude you need.
I give a program for calculating the table using
cabbage soup built-in calculator. She is enough
call exactly 1 time at the beginning of the program, and
then use the resulting table.
The program was pulled from 3D_LAME4k (personally
I always uploaded a ready-made table, but 4k..)
LD HL,#61OO: Address where
DESIN1 PUSH HL: builds a table
LD A,255 : faces
CALL 1156O
LD A,128
CALL 1156O
POP HL
PUSH HL
LD A,L
CALL 1156O
RST #28: Calling the calculator
DEFB #A3,4,1,5,#1F,4,#38
CALL 898O:^^^^^^^^^^^^^^
POP HL: Calculator codes.
LD(HL),A
INC L
J.P.P,DESIN1
LD D,H
LD E,L
SNS DEC HL
LD A,(HL)
LD(DE),A
INC E
JR NZ,SNS
RET
Attention!
a table will be built with 256 corners, not 36O
To improve performance and convenience
256 is specially taken, not 36O.
The calculation itself is carried out like this:
LD H,#61: Let's say there is a table here
LD L,N : N-Angle
LD A,(HL): Take the value of the sine
For cosine, a table is not needed because this is
shifted sine by 96 degrees. Just
add #6O to the angle and everything will be OK.
Rotate x,y,z axes
------------------
Let me remind you of Euler's formulas for those who have forgotten
around the x-axis:x'=x
y'= y*cos(fi) - z*sin(fi)
z'= y*sin(fi) + z*cos(fi)
around the y axis:
x'= x*cos(fi) + z*sin(fi)
y'=y
z'=-x*sin(fi) + z*cos(fi)
around the z axis:
x'= x*cos(fi) - y*sin(fi)
y'= x*sin(fi) + y*cos(fi)
z'=z
fi - angle
If you're not going to shortchange
perspective projection, then the calculation of z' can-
Feel free to discard it.
Well, now everything seems to be... :)
Share your thoughts about the article