PLOT3D161.S - 3D-Demo Version 1.61
********************************
* 3D-DEMO *
* *
* BY MARC GOLOMBECK *
* *
* VERSION 1.61 / 07.05.2017 *
* *
* NEEDS THE FOLLOWING DATA *
* ALREADY LOADED INTO MEMORY: *
* *
* $7000: SINE/COSINE-TABLE *
* $7200: POINT AND LINE DATA *
* $7400: SHAPE TABLE *
* $7A00: MULTIPLICATION TABLE *
* $8200: PROJECTION TABLE *
* *
* CONTROLLED VIA JOYSTICK AND *
* KEYBOARD: *
* *
* PDL(0/1): ROTATION+ZOOM *
* PBN(0/1): RESET+STOP/EXIT *
* KEYS 1-5: CHOOSE 3D-OBJECT *
* KEYS +/-: ALTERNATE ZOOM *
* KEY B : TOGGLE BENCHMARK *
* KEY Q : QUIT PROGRAM *
* *
********************************
*
ORG $6000
*
HGR2 EQU $F3D8 ; SWITCH TO HIRES2
HGR EQU $F3E2 ; SWITCH TO HIRES1
HCLR EQU $F3F2 ; CLEAR HIRES SCREEN TO BLACK1
HCOLOR EQU $F6F0 ; SET HCOLOR
HPOSN EQU $F411 ; SET HIRES-CURSOR NO DRAW
HPLOT EQU $F457 ; DRAW HIRES-PIXEL
HLIN EQU $F53A ; DRAW HIRES-LINE
PREAD EQU $FB1E ; READ PADDLES
PB0 EQU $C061 ; PUSH-BUTTON 0
PB1 EQU $C062 ; PUSH-BUTTON 1
PB2 EQU $C063 ; PUSH-BUTTON 2
HOME EQU $FC58 ; CLEAR SCREEN
COUT EQU $FDED ; PRINT CHARACTER
KYBD EQU $C000 ; READ KEYBOARD
STROBE EQU $C010 ; CLEAR KEYBOARD
SHNUM EQU $F730 ; GET ADRESS OF SHAPE NUMBER
SHDRAW EQU $F605 ; DRAW SHAPE ON SCREEN
BELL EQU $FBDD ; RING BELL
WAIT EQU $FCA8 ; WAIT A BIT
*
SINTAB EQU $7000 ; BASE ADRESS OF SINE TABLE
COSTAB EQU $7040 ; BASE ADRESS OF COSINE TABLE
NUMPNT EQU $7200 ; NUMBER OF POINTS TO DRAW
TABLE EQU $7201 ; BASE ADRESS FOR POINT TABLE
SHTAB EQU $7400 ; BASE ADRESS OF SHAPES-68
SSQLO EQU $7A00 ; MULT TAB PART 1
SSQHI EQU $7C00 ; MULT TAB PART 2
DSQLO EQU $7E00 ; MULT TAB PART 3
DSQHI EQU $8000 ; MULT TAB PART 4
PROJTAB EQU $8200 ; PROJECTION TAB
YLOOKLO EQU $8300 ; LOOKUP LINE BASE ADRESS
EVENCOL EQU $83C0 ; APPLESOFT CODE EVEN COLORS
ODDCOL EQU $83C8 ; APPLESOFT CODE UNEVEN COLORS
XORMASK EQU $83D0 ; PIXEL MASK
ANDMASK EQU $83D8 ; PIXEL MASK
LEMASK EQU $83DF
RIMASK EQU $83E6
YLOOKHI EQU $83ED ; LOOK LINE BASE ADRESS
COLLINE EQU $84AD
DIV7HI EQU $84D5 ; DIVISION BY 7 TABLE
MOD7HI EQU $84ED ; DIVISION BY 7 TABLE
DIV7LO EQU $8505 ; DIVISION BY 7 TABLE
MOD7LO EQU $8605 ; DIVISION BY 7 TABLE
*
XTRANS EQU $8B ; X-TRANSLATION CENTER SCREEN
YTRANS EQU $5F ; Y-TRANSLATION
ZTRANS EQU $FE ; MOVE 3D OBJECT AWAY FROM CAMERA
*
TXTPTR EQU $06 ; POINTER FOR TEXT OUTPUT
G_PAGE EQU $06 ; GRAPHIC PAGE TO DRAW TO
PTR EQU $08 ; POINTER FOR DOS COMMAND
PNTCNT EQU $09 ; WHICH POINT TO DRAW?
SCALE EQU $E7 ; SHAPE SCALE
SHTABPTR EQU $E8 ; POINTER TO SHAPE-TABLE
LOOPCNTY EQU $FA ; Y-ROT-COUNTER
ROTSPDY EQU $FB ; Y-ROTATIONAL SPEED
LOOPCNTX EQU $FC ; X-ROT-COUNTER
ROTSPDX EQU $FD ; X-ROTATIONAL SPEED
LOOPCNTZ EQU $F4 ; Z-ROT-COUNTER
ROTSPDZ EQU $F5 ; Z-ROTATIONAL SPEED
SCALING EQU $FF ; SCALING
*
SINX EQU $7B
XREGSAVE EQU $7B ; DOUBLE USE!
COSX EQU $7C
SINY EQU $7D
COSY EQU $7E
SINZ EQU $7F
COSZ EQU $80
PX1 EQU $85
PX2 EQU $87
PX3 EQU $89
PX4 EQU $8B
XTO EQU $89 ; DOUBLE USE
YTO EQU $8B ; DOUBLE USE
RX EQU $8D
RY EQU $8F
RZ EQU $91
QX EQU $93
QY EQU $94
XPOS EQU $95
YPOS EQU $96
ZPOS EQU $97
XD EQU $98
YD EQU $9A
TEMP1 EQU $EB ; TEMP STORAGE
TEMP2 EQU $EC ; TENP STORAGE
MKAND EQU $ED ; MULTIPLICANT
MATOR EQU $EF ; MULTIPLICATOR
*
XDRAW EQU $300 ; X-POSITION FOR DRAW
YDRAW EQU $302 ; Y-POSITION FOR DRAW
XDRAWO EQU $304 ; OLD POSITION X
YDRAWO EQU $306 ; OLD POSITION Y
XDRAW2 EQU $308 ; UNDRAW CURSOR X
YDRAW2 EQU $30A ; UNDRAW CURSOR Y
ASCR EQU $30B ; ACTIVE SCREEN TO DRAW
JOYCNT EQU $30C ; COUNTER FOR JOYSTICK REQUEST
BENCHM EQU $30D ; BENCHMARK ON?
MAXDRAW EQU $30E ; MAXIMUM LINES TO DRAW
HOLDON EQU $30F ; PAUSE PLOTTING
STEPON EQU $30A ; STEP FUNCTION
*
PSLO EQU $D8 ; USING FAC-ADRESS RANGE
PSHI EQU $DA ; FOR POINTER IN MULT-TAB
PDLO EQU $DC ; USING ARG-ADRESS RANGE
PDHI EQU $DE ; FOR POINTER IN MULT-TAB
*
ENTRY JSR SETUP ; SETUP GRAPHIC & VARIABLES
*
TABLESET JSR WLCMTXT ; DRAW TOP & BOTTOM TEXT
*
* READ PADDELS
*
LOOP INC JOYCNT ; MAIN LOOP STARTS HERE
LDA HOLDON ; IS HOLDON ACTIVATED?
BEQ EVJOY ; NO
LDA STEPON ; DO A STEP?
BNE DOSTEP ; YES -> ONE STEP
JMP READKBD
DOSTEP DEC STEPON ; RESET STEP-TRIGGER
EVJOY LDA JOYCNT ; EAVLUATE JOYSTICK
CMP #$04
BCC READ1
LDA #$00 ; READ PADDLE EVERY 2 CYCLES
STA JOYCNT
*
PREAD0 LDX #$00 ; VARY Y-ROT SPEED
JSR PREAD ; PADDLE (0)
CPY #$64
BCC INCSPDY ; DECREASE SPEED
CPY #$9B
BCS DECSPDY ; INCREASE SPEED
BCC PREAD1 ; 256-STEP CIRCLE LOOP
*
DECSPDY LDA ROTSPDY ; DECREASE ANGLE
CMP #$02
BCC PREAD1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDY
DEC ROTSPDY
JMP PREAD1 ; JUMP TO NEXT COMMAND
INCSPDY LDA ROTSPDY ; DECREASE WAIT COUNTER
CMP #$20
BCS PREAD1 ; MAXIMUM 10
INC ROTSPDY
INC ROTSPDY
*
PREAD1 LDX #$01 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
BCC DECSPDX ; DECREASE SPEED
CPY #$9B
BCS INCSPDX ; INCREASE SPEED
BCC READ1 ; 256-STEP CIRCLE LOOP
*
DECSPDX LDA ROTSPDX ; DECREASE ANGLE
CMP #$02
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDX
DEC ROTSPDX
JMP READ1 ; JUMP TO NEXT COMMAND
INCSPDX LDA ROTSPDX ; DECREASE WAIT COUNTER
CMP #$20
BCS READ1 ; MAXIMUM 10
INC ROTSPDX
INC ROTSPDX
*
READ1 CLC ; CALC NEXT STEP
LDX #$00
LDA LOOPCNTY
BPL READ02
INX ; INIT FOR BENCHMARK
READ02 ADC ROTSPDY ; ADD NEXT STEP
CLC
ADC #$F6 ; ACCU = ACCU -10
STA LOOPCNTY
LDA LOOPCNTY
BPL READ01 ;
INX
READ01 CPX #01
BNE READ03 ; BENCHMARK LOOP START
LDY BENCHM
BEQ READ03 ; BENCHMARK OFF
JSR BELL ; REING BELL
*
READ03 CLC ; X-ROTATION
LDA LOOPCNTX
ADC ROTSPDX ; ADD NEXT STEP
CLC
ADC #$F6 ; ACCU = ACCU - 10
STA LOOPCNTX
CLC ; Z-ROTATION
LDA LOOPCNTZ
ADC ROTSPDZ
CLC
ADC #$F6
STA LOOPCNTZ
*
JSR INITPNTS ; CALC NEW POINT POSITIONS
JSR UDRWLNS ; UNDRAW LINES
JSR DRWLNS
*
* READ KEYBOARD FOR LOADING NEW OBJECTS
*
READKBD LDA KYBD
BPL NOKEY1 ; NO KEY IS PRESSED
KEYPOINT CMP #$AE ; KEY '.' IS PRESSED
BNE KEYCOMMA
INCSPDZ LDA ROTSPDZ ; INCREASE Z-ROTATION SPEED
CMP #$20
BCS NOINCZ ; MAXIMUM 10
INC ROTSPDZ
INC ROTSPDZ
NOINCZ JMP ENDKEY1
KEYCOMMA CMP #$AC ; KEY "," IS PRESSED
BNE KEY1
DECSPDZ LDA ROTSPDZ ; DECREASE ANGLE
CMP #$02
BCC NODECZ ; LOOPCNT STILL POSITIVE
DEC ROTSPDZ
DEC ROTSPDZ
NODECZ JMP ENDKEY1
KEY1 CMP #$B1 ; KEY '1' IS PRESSED
BNE KEY2
JSR LOAD1 ; LOAD OBJECT 1
JMP ENDKEY
KEY2 CMP #$B2 ; KEY '2' IS PRESSED
BNE KEY3
JSR LOAD2
JMP ENDKEY
KEY3 CMP #$B3 ; KEY '3' IS PRESSED
BNE KEY4
JSR LOAD3
JMP ENDKEY
KEY4 CMP #$B4 ; KEY '4' IS PRESSED
BNE KEY5
JSR LOAD4
JMP ENDKEY
KEY5 CMP #$B5 ; KEY '5' IS PRESSED
BNE KEYPLUS
JSR LOAD5
JMP ENDKEY
NOKEY1 BPL NOKEY ; INTERMEDIATE JUMP
KEYPLUS CMP #$AB ; KEY '+' IS PRESSED
BNE KEYMINUS
LDA STROBE
LDA ZTRANS ; INCREASE DISTANCE
CMP #$30 ; WAS $7F
BCC ENDKEY1 ; MAIXMUM 127
DEC ZTRANS
DEC ZTRANS
DEC ZTRANS
DEC ZTRANS
BNE ENDKEY1
KEYMINUS CMP #$AD ; KEY '-' IS PRESSED
BNE KEYQ
LDA STROBE
LDA ZTRANS ; DECREASE DISTANCE
CMP #$D0 ; WAS $43
BCS ENDKEY1 ; LOOPCNT STILL POSITIVE
INC ZTRANS
INC ZTRANS
INC ZTRANS
INC ZTRANS
BNE ENDKEY1 ; JUMP TO NEXT COMMAND
KEYQ CMP #$D1 ; KEY 'Q' IS PRESSED
BNE KEYB
LDA STROBE
JMP END ; END PROGRAM
KEYB CMP #$C2 ; KEY 'B' IS PRESSED
BNE KEYS
LDA BENCHM ; TOGGLE BENCHMARK ON/OFF
BEQ BENCHON
DEC BENCHM ; TOGGLE OFF
BEQ ENDKEY1
BENCHON INC BENCHM ; TOGGLE ON
BNE ENDKEY1
KEYS CMP #$D3 ; KEY 'S' IS PRESSED
BNE KEYH
LDA STEPON ; TOGGLE BENCHMARK ON/OFF
BEQ SSTEPON
DEC STEPON ; TOGGLE OFF
BEQ ENDKEY1
SSTEPON INC STEPON ; TOGGLE ON
BNE ENDKEY1
KEYH CMP #$C8 ; KEY 'H' IS PRESSED
BNE NOKEY
LDA HOLDON ; TOGGLE BENCHMARK ON/OFF
BEQ HHOLDON
DEC HOLDON ; TOGGLE OFF
BEQ ENDKEY1
HHOLDON INC HOLDON ; TOGGLE ON
BNE ENDKEY1
ENDKEY JSR SETUP
JSR WLCMTXT ; WRITE TOP & BOTTOM TEXT
JSR INITPNTS ; SET INITIAL POINT POSITION
ENDKEY1 LDA STROBE ; CLEAR KEYPRESS
*
* CHECK PUSHBUTTONS
*
NOKEY LDA PB1 ; PB 1 PRESSED?
BMI END ; EXIT PROGRAM!
PB0CHK LDA PB0 ; PB 0 PRESSED?
BPL GOLOOP ; NO -> DO NEXT LOOP
LDA #$00 ; RESET ASPECT AND STOP ROTATION
STA LOOPCNTX ; BACK TO INIT POS
STA LOOPCNTY
STA LOOPCNTZ
LDA #$0A
STA ROTSPDY ; STOP ROTATION
STA ROTSPDX
STA ROTSPDZ
*
GOLOOP JMP LOOP ; START AGAIN
*
END LDA #$00 ; END PROGRAM
STA $C051 ; SWITCH TO TEXT
STA $C052
STA $C054
JSR HOME ; CLEAR SCREEN
JMP $03D0 ; DOS WARM START NO RTS HERE!
*
********************************
* SETUP GRAPHICS & DATA *
********************************
*
SETUP LDA #$00
STA $C050 ; SWITCH ON GRAPHICS
STA $C057 ; SWITCH TO HIRES
STA BENCHM ; BENCHMARK OFF
STA HOLDON ; HOLD-FUNCTION DEACTIVATED
STA STEPON ; STEP-FUNCTION DEACTIVATED
*
LDA #SHTAB
STA SHTABPTR+1
LDA #$01
STA SCALE ; SCALE = 1
*
LDA #32
STA $E6 ; DRAW ON 1
STA $C055 ; SHOW 2
JSR HCLR ; CLEAR HGR
JSR DRAWBOX ; DRAW BOX ON HIRES 1
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #64
STA $E6 ; DRAW ON 2
STA $C054
JSR HCLR ; CLEAR HGR2
JSR DRAWBOX ; DRAW BOX ON HIRES 2
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
LDX #11
LDY #01 ; XPOS = 267
LDA #09
JSR HPOSN
LDX #69
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #$03 ; INIT HCOLOR = 3
JSR HCOLOR
LDA #$0A
STA ROTSPDX ; INIT X-ROT SPEED = 0
STA ROTSPDZ ; INIT Z-ROT SPEED = 0
LDA #$0F
STA ROTSPDY ; INIT Y-ROT SPEED = 1
*
LDA #$00 ; DEFINED POSITIONS AFTER
STA LOOPCNTY ; STARTING THE ALGO OR
STA LOOPCNTZ ; CHANGING 3D-OBJECTS
LDA #$10
STA LOOPCNTX ; CURRENT X-STEP
*
LDA #$01
STA ASCR ; DRAW ON HIRES 1
STA JOYCNT ; SET JOYSTICK REQUEST COUNTER
*
LDA #$30 ; SCALING
STA SCALING
LDA #$50
STA ZTRANS ; MOVE OBJECT AWAY FROM CAMERA
*
LDA #SSQLO/256 ; SETUP MULT-TAB
STA PSLO+1
LDA #SSQHI/256
STA PSHI+1
LDA #DSQLO/256
STA PDLO+1
LDA #DSQHI/256
STA PDHI+1
*
*
RTS
*
********************************
* DRAW LINES *
********************************
*
DRWLNS LDA #$00
STA PNTCNT
LDA ASCR ; CHECK WHICH SCREEN IS ACTIVE
CMP #$01
BEQ DRWSCR10
LDA #$40 ; SCREEN 2 IS ACTIVE
BPL DP1 ; ALWAYS POSITIVE
DRWSCR10 LDA #$20 ; SCREEN 1 IS ACTIVE
DP1 STA G_PAGE
GETPNT2 LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX ; SKIP 3 BYTES
INX
INX
LDA TABLE,X ; GET XPOS LO-BYTE
STA XDRAW
INX
LDA TABLE,X ; GET XPOS HI-BYTE
STA XDRAW+1
INX
LDA TABLE,X ; GET YPOS
STA YDRAW
INX
INX ; SKIP 6 BYTES
INX
INX
INX
INX
INX
LDA #$04
STA MAXDRAW ; NUMBER OF LINES TO DRAW
STX XREGSAVE ; SAVE X-REG ON STACK
*
* EVALUATE POINTS TO DRAW TO
*
LDX XREGSAVE
DRWNXT LDA TABLE,X
BEQ NXTPNT ; NOTHING MORE TO DRAW
TAY ; SUBTRACT 1 TO GET CORREC
DEY ; POINT NUMBER
TYA
ASL ; CALC BASE ADRESS OF POINT TO
ASL ; DRAW TO
ASL
ASL
TAY ; Y = POINNUMBER * 16
INY ; SKIP 3 BYTES
INY
INY
LDA TABLE,Y ; READ OUT POINTS TO DRAW TO
STA XTO
INY
LDA TABLE,Y
STA XTO+1
INY
LDA TABLE,Y
STA YTO
*
STX XREGSAVE
JSR LINEDRAW ; DO FAST LINE DRAW
LDX XREGSAVE
*
DEC MAXDRAW ; MAXIMUM NUMBER OF LINES
BEQ NXTPNT ; REACHED? IF YES NEXT POINT
INX ; NEXT POINT
BNE DRWNXT
*
NXTPNT INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS DRWEND ; ALL DONE
JMP GETPNT2
DRWEND LDA ASCR ; DISPLAY DRAW-SCREEN
CMP #$02
BEQ DISP2 ; SHOW SCREEN 2
LDA #64
STA $E6 ; DRAW ON 2
STA $C054 ; SWITCH TO SCREEN1
INC ASCR ; ASCR = 2
BNE DRWEND2
DISP2 STA $C055 ; SWITCH TO SCREEN2
LDA #32
STA $E6 ; DRAW ON 1
DEC ASCR ; ASCR = 1
DRWEND2 RTS
*
*
********************************
* INIT POINT POSITIONS *
********************************
*
INITPNTS LDA #$00
STA PNTCNT
*
* EVAL SIN/COS-TAB
*
LDX LOOPCNTX ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR X
STA SINX
LDA COSTAB,X ; GET COSINUS FOR X
STA COSX
LDX LOOPCNTY
LDA SINTAB,X
STA SINY
LDA COSTAB,X
STA COSY
LDX LOOPCNTZ
LDA SINTAB,X
STA SINZ
LDA COSTAB,X
STA COSZ
*
* ROTATE POINTS AROUND X AND Y
*
GETPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
LDA TABLE,X ; GET XPOS
STA XPOS
INX
LDA TABLE,X ; GET YPOS
STA YPOS
INX
LDA TABLE,X ; GET ZPOS
STA ZPOS
*
* PERFORM Y-ROTATION
*
STRTROT LDA XPOS ; RX = X * COS(Y) + Z * SIN(Y)
STA MATOR ; X * COS(Y)
LDA COSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA SINY ; XPOS STILL IN MATOR!
STA MKAND ; X * SIN(Y)
JSR MULT
STA PX4
STY PX4+1
LDA ZPOS ; Z * SIN(Y)
STA MATOR
LDA SINY
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA COSY ; RZ = Z * COS(Y) - X * SIN(Y)
STA MKAND ; ZPOS STILL IN MATOR
JSR MULT ; Z * COS(Y)
STA PX3
STY PX3+1
CLC ; X-CCORD: ADD
LDA PX1
ADC PX2
STA RX
LDA PX1+1
ADC PX2+1
STA RX+1 ; SAVE HI-BYTE AS XPOS
*
SEC ; Z-COORD: SUB
LDA PX3
SBC PX4
STA RZ
LDA PX3+1
SBC PX4+1
STA RZ+1
*
LDA YPOS ; RY = YPOS * 1 (=$7F)
STA MATOR
LDA #$7F
STA MKAND
JSR MULT
STA RY
STY RY+1
*
* PERFORM X-ROTATION
*
LDA RX+1 ; RXNEW = RX+1 * 1 (=$7F)
STA MATOR
LDA #$7F
STA MKAND
JSR MULT
STA RX
STY RX+1
*
LDA RY+1 ; RY = Y * COS(X) - Z * SIN(X)
STA MATOR ; Y * COS(X)
LDA COSX
STA MKAND
JSR MULT
STA PX1
STY PX1+1
*
LDA SINX ; CALC Y * SIN(X) FOR Z-COORD
STA MKAND ; Y * SIN(X)
JSR MULT
STA PX3
STY PX3+1
*
LDA RZ+1 ; Z * SIN(X)
STA MATOR
LDA SINX
STA MKAND
JSR MULT
STA PX2
STY PX2+1
*
LDA COSX ; CALC Z * COS(X) FOR Z-CCORD
STA MKAND ; Z * COS(X)
JSR MULT
STA PX4
STY PX4+1
*
SEC ; Y-COORD: SUB
LDA PX1
SBC PX2
STA RY
LDA PX1+1
SBC PX2+1
STA RY+1
*
CLC ; Z-COORD: ADD + TRANSLATE
LDA PX3
ADC PX4
STA RZ
LDA PX3+1
ADC PX4+1
CLC
ADC ZTRANS ; Z-TRANSLATION AND SCALE DOWN
LSR
LSR
STA RZ+1
*
* PERFORM Z-ROTATION
*
* DO NOT TOUCH RZ ANYMORE!
*
LDA RX+1 ; RX = X * COSZ - Y * SINZ
STA MATOR ; X * COS(Z)
LDA COSZ
STA MKAND
JSR MULT
STA PX1
STY PX1+1
*
LDA SINZ ; X * SIN(Z)
STA MKAND
JSR MULT
STA PX3
STY PX3+1
*
LDA RY+1 ; Y * SIN(Z)
STA MATOR
LDA SINZ
STA MKAND
JSR MULT
STA PX2
STY PX2+1
*
LDA COSZ ; Y * COS(Z)
STA MKAND
JSR MULT
STA PX4
STY PX4+1
*
SEC ; NOW CALCULATE NEW RX
LDA PX1 ; SINCE OLD RX IS NEEDED FOR
SBC PX2 ; RY-CACLULUS BEFORE!
STA RX
LDA PX1+1
SBC PX2+1
STA RX+1
*
CLC ; Y-COORD: ADD
LDA PX3
ADC PX4
STA RY
LDA PX3+1
ADC PX4+1
STA RY+1
*
* PERFORM SCALING AND TRANSLATION
*
ASL RX
ROL RX+1
ASL RX
ROL RX+1
ASL RY
ROL RY+1
ASL RY
ROL RY+1
*
LDX RZ+1 ; LOAD PROJECTION
LDA PROJTAB,X
STA MATOR
LDA RX+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STY QX
*
LDA RY+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STY QY
*
CLC ; XD = QX + XT
LDA QX
ADC #XTRANS
STA XD
LDA #$00
STA XD+1
LDA QX
BMI CALCYD ; IF QX < 0 THEN DO NOT ADD CARRY!
LDA #$00
ADC #$00 ; ADD CARRY BIT
STA XD+1
CALCYD CLC ; YD = QY + YT
LDA QY
ADC #YTRANS
STA YD ; ONLY 1 BYTE HERE, NO CARRY!
*
* WRITE DATA BACK TO TABLE
*
WRTPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX
INX
INX ; SKIP 3 BYTES
LDA XD ; SAVE XDRAW POSITION
STA TABLE,X
INX
LDA XD+1
STA TABLE,X
INX
LDA YD ; SAVE YDRAW POSITION
STA TABLE,X
*
INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS INITEND ; ALL DONE
JMP GETPNT
INITEND RTS
*
CYC OFF
*
********************************
* DRAW BOX AROUND HIRES SCREEN *
********************************
*
DRAWBOX LDX #$03
JSR HCOLOR
LDA #$00
TAY
TAX
JSR HPLOT
LDA #23
LDX #01
JSR HLIN
*
LDA #23
LDX #01
LDY #$BF
JSR HLIN
*
LDA #$00
LDX #$00
LDY #$BF
JSR HLIN
*
LDA #$00
TAY
TAX
JSR HLIN
*
LDY #00
LDX #00
LDA #12
JSR HPOSN
*
LDA #23
LDX #01
LDY #12
JSR HLIN
RTS
*
********************************
*SIGNED DIVISION 16 BIT/8 BIT *
********************************
*
CYC
*
DIVI STY DEND ;
STA DEND+1
STX DOR
*
LDX #$00
DECHK LDA DEND+1 ; DIVIDEND NEG?
BPL DORCHK
INX ; INC X-REG FOR NEG SIGN
LDA DEND
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DEND
LDA DEND+1
SBC #$00
EOR #$FF
STA DEND+1
DORCHK LDA DOR ; DIVISOR NEG?
BPL DIVIGO
INX ; INC X-REG FOR NEG SIGN
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DOR
*
DIVIGO LDA DEND+1 ; TOO LARGE OR ZERO?
CMP DOR ; CMP HI-BYTE WITH DOR!
BCC DLOOP ; NO -> NO ERROR!
JMP DIVERR ; YES -> ERROR!
DLOOP ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP2
DSUBTR SBC DOR
INC DEND
DLOOP2 ASL DEND
ROL
BCS DSUBTR2
CMP DOR
BCC DLOOP3
DSUBTR2 SBC DOR
INC DEND
DLOOP3 ASL DEND
ROL
BCS DSUBTR3
CMP DOR
BCC DLOOP4
DSUBTR3 SBC DOR
INC DEND
DLOOP4 ASL DEND
ROL
BCS DSUBTR4
CMP DOR
BCC DLOOP5
DSUBTR4 SBC DOR
INC DEND
DLOOP5 ASL DEND
ROL
BCS DSUBTR5
CMP DOR
BCC DLOOP6
DSUBTR5 SBC DOR
INC DEND
DLOOP6 ASL DEND
ROL
BCS DSUBTR6
CMP DOR
BCC DLOOP7
DSUBTR6 SBC DOR
INC DEND
DLOOP7 ASL DEND
ROL
BCS DSUBTR7
CMP DOR
BCC DLOOP8
DSUBTR7 SBC DOR
INC DEND
DLOOP8 ASL DEND
ROL
BCS DSUBTR8
CMP DOR
BCC DCONT
DSUBTR8 SBC DOR
INC DEND
*
* STORE RESULTS
*
DCONT STA DOR ; MOVE REMAINDER IN DOR
CLC ; NO ERROR -> CLEAR CARRY
CPX #$01 ; NEG SIGN FOR RESULT?
BNE DIVEND ; NO, SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA DOR
LDA DEND
EOR #$FF
ADC #$01
STA DEND
LDA DOR ; DOR = REMAINDER
DIVEND LDY DEND ; DEND = QUOTIENT
BNE DIVRTS
INY
DIVRTS RTS
DIVERR LDY #$00 ; RETURN 0 AS RESULT
RTS
*
CYC OFF
*
DEND DS 2
DOR DS 1
*
********************************
* 8-BIT UNSIGNED FAST MULTIPLY *
********************************
*
CYC
*
UMULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
UMTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSHI
EOR #$FF
STA PDHI
SEC
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL UMDONE ; NO -> ALL DONE
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
UMDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
RTS
*
CYC OFF
*
*
********************************
* 8-BIT SIGNED COMPL MULTIPLY *
********************************
*
CYC
*
MULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
MTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSLO ; INDEX INTO SUM TABLE BY A
STA PSHI
EOR #$FF
STA PDLO ; INDEX INTO DIFF TABLE BY -A-1
STA PDHI
LDA (PSLO),Y ; GET (A+Y)^2/4 (LO BYTE)
SEC
SBC (PDLO),Y ; SUBTRACT (-A+Y)^2/4 (LO BYTE)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL CHKT2 ; NO CHECK MATOR
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
CHKT2 LDY TEMP2 ; CHECK IF MATOR < 0
BPL MDONE ; NO, RTS
SEC ; MATOR STILL IN ACCU
SBC TEMP1 ; SUBTRACT TEMP1 FROM MATOR
*
MDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
LDA MKAND ; LOAD LO BYTE
RTS
*
CYC OFF
*
********************************
* 8-BIT SIGNED FAST MULTIPLY *
********************************
*
CYC
*
FMULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
FMTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSHI
EOR #$FF
STA PDHI
SEC
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL FCHKT2 ; NO CHECK MATOR
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
FCHKT2 LDY TEMP2 ; CHECK IF MATOR < 0
BPL FMDONE ; NO, RTS
SEC ; MATOR STILL IN ACCU
SBC TEMP1 ; SUBTRACT TEMP1 FROM MATOR
*
FMDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
RTS
*
CYC OFF
*
********************************
* TOP & BOTTOM TEXT MESSAGE *
********************************
*
* PRINT OUT WELCOME TEXT AS SHAPES ON SCREEN
*
WLCMTXT LDX #$03
JSR HCOLOR
STX $F9 ; SET ROT = 0
LDA #$01
STA SCALE ; SET SCALE = 1
LDX #$00
TXTLOOP LDA TXTDAT,X
BEQ TLP2 ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #26 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX XREGDUMP
INX
BNE TXTLOOP
*
TLP2 LDX #$00
TXTLOOP2 LDA TXTDAT2,X
BEQ SUDONE
STA SHPDUMP
STX XREGDUMP
TXA
ASL
ASL
ASL
CLC
ADC #18
TAX
STX SHXPOS
LDY #$00
LDA #188
JSR HPOSN
*
LDX SHPDUMP
JSR SHNUM
LDA #32
STA $E6
LDA #$00
JSR SHDRAW
*
LDX SHXPOS
LDY #$00
LDA #188
JSR HPOSN
LDX SHPDUMP
JSR SHNUM
LDA #64
STA $E6
LDA #$00
JSR SHDRAW
LDX XREGDUMP
INX
BNE TXTLOOP2
SUDONE RTS
*
* TEXT MESSAGES WHEN LOADING 3D-OBJECTS
*
TXTOB1 LDA #TXTDAT3
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB2 LDA #TXTDAT4
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT
*
TXTOB3 LDA #TXTDAT5
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT
*
TXTOB4 LDA #TXTDAT6
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT
*
TXTOB5 LDA #TXTDAT7
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT
*
PRTTXT LDY #$00
LDX #$03
JSR HCOLOR ; SET HCOLOR = 3
TXTLOOP3 LDA (TXTPTR),Y
BEQ TXTDONE
STA SHPDUMP
STY YREGDUMP
TYA
ASL
ASL
ASL
CLC
ADC #18
TAY
TAX
STY SHXPOS
LDY #$00
LDA #188
JSR HPOSN
*
LDX SHPDUMP
JSR SHNUM
LDA #32
STA $E6
LDA #$00
JSR SHDRAW
*
LDX SHXPOS
LDY #$00
LDA #188
JSR HPOSN
LDX SHPDUMP
JSR SHNUM
LDA #64
STA $E6
LDA #$00
JSR SHDRAW
*
LDY YREGDUMP
INY
BNE TXTLOOP3
TXTDONE RTS
*
TXTDAT HEX 292231313A01151135
HEX 2901232A33352925223A
HEX 012231312D26013E3C
HEX 00
*
TXTDAT2 HEX 450114250E25262E3001
HEX 0E012E0F28302D30
HEX 2E2326242C01131112
HEX 18014500
*
TXTDAT3 HEX 2D3022252A2F28013529
HEX 2601352635332226252633
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT4 HEX 2D3022252A2F28013529
HEX 2601362E2333262D2D22
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT5 HEX 2D3022252A2F28013529
HEX 2601342A2E312D260124362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT6 HEX 2D3022252A2F28013529
HEX 2601352635332224362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT7 HEX 2D3022252A2F28013529
HEX 2601243623260135382A2F34
HEX 0F0F0F010101010101
HEX 010100
*
LCNT DS 1
XREGDUMP DS 1
YREGDUMP DS 1
SHPDUMP DS 1
SHXPOS DS 1
*
* DELETE BOTTOM TEXT
*
DLTTXT LDX #$00
JSR HCOLOR ; HCOLOR = 0
LDA ASCR
DLTSTRT LDA #180
STA YDELROW ; Y OF LINE TO DELETE
DLTLOOP LDA #32
STA $E6 ; DELETE ON SCREEN 1
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
LDA #64
STA $E6 ; DELETE ON SCREEN 2
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
INC YDELROW
LDA YDELROW
CMP #189 ; LINE 189 REACHED?
BCC DLTLOOP ; NO -> DELETE NEXT LINE
DLTEND RTS ; END OF LOOP
*
YDELROW DS 1
*
********************************
* LOAD 3D-OBJECTS IN MEMORY *
********************************
*
LOAD1 JSR TXTOB1 ; PRINT LOADING MESSAGE
LOAD01 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT1.3D,A$7200"
HEX 8D00
RTS
*
LOAD2 JSR TXTOB2
LOAD02 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT2.3D,A$7200"
HEX 8D00
RTS
*
LOAD3 JSR TXTOB3
LOAD03 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT3.3D,A$7200"
HEX 8D00
RTS
*
LOAD4 JSR TXTOB4
LOAD04 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT4.3D,A$7200"
HEX 8D00
RTS
*
LOAD5 JSR TXTOB5
LOAD05 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT5.3D,A$7200"
HEX 8D00
RTS
*
PRINT PLA
STA PTR
PLA
STA PTR+1
LDY #$01
P0 LDA (PTR),Y
BEQ PFIN
JSR COUT
INY
BNE P0
CHK
*
PFIN CLC
TYA
ADC PTR
STA PTR
LDA PTR+1
ADC #$00
PHA
LDA PTR
PHA
PEXIT RTS
*
********************************
* UNDRAW LINES *
********************************
*
UDRWLNS LDA #$00
*
LDY $E6
CPY #$20
BEQ UDRWSCR1
JMP UDRWSCR2
UDRWSCR1 LDX #$0B
UDRWLP1 STA $2200,X
STA $2600,X
STA $2A00,X
STA $2E00,X
STA $3200,X
STA $3600,X
STA $3A00,X
STA $3E00,X
STA $2280,X
STA $2680,X
STA $2A80,X
STA $2E80,X
STA $3280,X
STA $3680,X
STA $3A80,X
STA $3E80,X
STA $2300,X
STA $2700,X
STA $2B00,X
STA $2F00,X
STA $3300,X
STA $3700,X
STA $3B00,X
STA $3F00,X
STA $2380,X
STA $2780,X
STA $2B80,X
STA $2F80,X
STA $3380,X
STA $3780,X
STA $3B80,X
STA $3F80,X
STA $2028,X
STA $2428,X
STA $2828,X
STA $2C28,X
STA $3028,X
STA $3428,X
STA $3828,X
STA $3C28,X
STA $20A8,X
STA $24A8,X
STA $28A8,X
STA $2CA8,X
STA $30A8,X
STA $34A8,X
STA $38A8,X
STA $3CA8,X
STA $2128,X
STA $2528,X
STA $2928,X
STA $2D28,X
STA $3128,X
STA $3528,X
STA $3928,X
STA $3D28,X
STA $21A8,X
STA $25A8,X
STA $29A8,X
STA $2DA8,X
STA $31A8,X
STA $35A8,X
STA $39A8,X
STA $3DA8,X
STA $2228,X
STA $2628,X
STA $2A28,X
STA $2E28,X
STA $3228,X
STA $3628,X
STA $3A28,X
STA $3E28,X
STA $22A8,X
STA $26A8,X
STA $2AA8,X
STA $2EA8,X
STA $32A8,X
STA $36A8,X
STA $3AA8,X
STA $3EA8,X
STA $2328,X
STA $2728,X
STA $2B28,X
STA $2F28,X
STA $3328,X
STA $3728,X
STA $3B28,X
STA $3F28,X
STA $23A8,X
STA $27A8,X
STA $2BA8,X
STA $2FA8,X
STA $33A8,X
STA $37A8,X
STA $3BA8,X
STA $3FA8,X
*
STA $2050,X
STA $2450,X
STA $2850,X
STA $2C50,X
STA $3050,X
STA $3450,X
STA $3850,X
STA $3C50,X
STA $20D0,X
STA $24D0,X
STA $28D0,X
STA $2CD0,X
STA $30D0,X
STA $34D0,X
STA $38D0,X
STA $3CD0,X
STA $2150,X
STA $2550,X
STA $2950,X
STA $2D50,X
STA $3150,X
STA $3550,X
STA $3950,X
STA $3D50,X
STA $21D0,X
STA $25D0,X
STA $29D0,X
STA $2DD0,X
STA $31D0,X
STA $35D0,X
STA $39D0,X
STA $3DD0,X
INX
CPX #29
BEQ UDRW1RTS
JMP UDRWLP1
UDRW1RTS RTS
UDRWSCR2 LDX #$0B
UDRWLP2 STA $4200,X
STA $4600,X
STA $4A00,X
STA $4E00,X
STA $5200,X
STA $5600,X
STA $5A00,X
STA $5E00,X
STA $4280,X
STA $4680,X
STA $4A80,X
STA $4E80,X
STA $5280,X
STA $5680,X
STA $5A80,X
STA $5E80,X
STA $4300,X
STA $4700,X
STA $4B00,X
STA $4F00,X
STA $5300,X
STA $5700,X
STA $5B00,X
STA $5F00,X
STA $4380,X
STA $4780,X
STA $4B80,X
STA $4F80,X
STA $5380,X
STA $5780,X
STA $5B80,X
STA $5F80,X
STA $4028,X
STA $4428,X
STA $4828,X
STA $4C28,X
STA $5028,X
STA $5428,X
STA $5828,X
STA $5C28,X
STA $40A8,X
STA $44A8,X
STA $48A8,X
STA $4CA8,X
STA $50A8,X
STA $54A8,X
STA $58A8,X
STA $5CA8,X
*
STA $4128,X
STA $4528,X
STA $4928,X
STA $4D28,X
STA $5128,X
STA $5528,X
STA $5928,X
STA $5D28,X
STA $41A8,X
STA $45A8,X
STA $49A8,X
STA $4DA8,X
STA $51A8,X
STA $55A8,X
STA $59A8,X
STA $5DA8,X
STA $4228,X
STA $4628,X
STA $4A28,X
STA $4E28,X
STA $5228,X
STA $5628,X
STA $5A28,X
STA $5E28,X
STA $42A8,X
STA $46A8,X
STA $4AA8,X
STA $4EA8,X
STA $52A8,X
STA $56A8,X
STA $5AA8,X
STA $5EA8,X
STA $4328,X
STA $4728,X
STA $4B28,X
STA $4F28,X
STA $5328,X
STA $5728,X
STA $5B28,X
STA $5F28,X
STA $43A8,X
STA $47A8,X
STA $4BA8,X
STA $4FA8,X
STA $53A8,X
STA $57A8,X
STA $5BA8,X
STA $5FA8,X
*
STA $4050,X
STA $4450,X
STA $4850,X
STA $4C50,X
STA $5050,X
STA $5450,X
STA $5850,X
STA $5C50,X
STA $40D0,X
STA $44D0,X
STA $48D0,X
STA $4CD0,X
STA $50D0,X
STA $54D0,X
STA $58D0,X
STA $5CD0,X
STA $4150,X
STA $4550,X
STA $4950,X
STA $4D50,X
STA $5150,X
STA $5550,X
STA $5950,X
STA $5D50,X
STA $41D0,X
STA $45D0,X
STA $49D0,X
STA $4DD0,X
STA $51D0,X
STA $55D0,X
STA $59D0,X
STA $5DD0,X
INX
CPX #29
BEQ UDRW2RTS
JMP UDRWLP2
UDRW2RTS RTS
*
********************************
* FAST LINE DRAW *
********************************
*
*
HBASL EQU $07 ; DOUBLE ZPAGE ADRESS USE!!!
XPOSL EQU $7C
XPOSH EQU $7D
YPOSN EQU $7E
DELTAXL EQU $7F
DELTAXH EQU $80
DELTAY EQU $85
COUNT EQU $86
COUNTH EQU $87
DIFF EQU $88
DIFFH EQU $8D
ANDMSK EQU $8E
WIDEFLAG EQU $8F
*
LINEDRAW LDA XTO ; WHICH X-VALUE IS ON THE LEFT?
SEC
SBC XDRAW
TAX
BEQ CHKVERT ; LOW BYTE EVEN CHECK VERTICAL
LDA XTO+1
SBC XDRAW+1
BCS LX0LEFT
*
LX0RIGHT EOR #$FF ; INVERT HI-BYTE
STA DELTAXH ; STORE HI-BYTE
TXA
EOR #$FF ; INVERT LO-BYTE
STA DELTAXL
INC DELTAXL ; TWO'S COMPLEMENT
BNE NOINCHI ; ROLLED INTO HI-BYTE?
INC DELTAXH ; YES
NOINCHI LDA XTO ; START WITH XTO
STA XPOSL
LDA XTO+1
STA XPOSH
LDA YTO
STA YPOSN
SEC
SBC YDRAW ; DELTA-Y?
JMP LNCOMMON
*
CHKVERT LDA XTO+1 ; DIFF IN HI-BYTES?
SBC XDRAW+1 ; CARRY STILL SET
BLT LX0RIGHT ; WIDTH = 256, XDRAW RIGHT
BNE LX0LEFT ; WIDTH = 256, XDRAW LEFT
JMP VERTLINE
*
LX0LEFT STX DELTAXL ; XDRAW IS LEFT
STA DELTAXH
LDA XDRAW ; START WITH XDRAW
STA XPOSL
LDA XDRAW+1
STA XPOSH
LDA YDRAW
STA YPOSN ; GET DELTA-Y
SEC
SBC YTO
*
LNCOMMON BCS LPOSY
EOR #$FF ; INVERT IF NEGATIVE
ADC #$01
STA DELTAY
LDA #$E8 ; INX
BNE GOTDY
LPOSY STA DELTAY
LDA #$CA ; DEX
GOTDY STA LHMODY ; SELF-MODIFYING CODE
STA LVMODY
STA LWMODY
*
* CHECK DOMINANCE
*
LDY #$01
LDA DELTAXL
LDX DELTAXH
BNE HORIDOM ; WIDTH > 256
CMP #$FF ; WIDTH = 255
BEQ HORIDOM
DEY ; NOT WIDE
CMP DELTAY
BGE HORIDOM ; IF DIAGONAL
JMP VERTDOM
*
HORIDOM STY WIDEFLAG ; HORIZONTAL IS DOMINANT
STA COUNT ; COUNT = DELTAX + 1
INC COUNT
LSR ; DIFF = DELTAX / 2
STA DIFF
*
LDX XPOSL
LDA XPOSH ; >= 256?
BEQ LOTABLE ; NO -> USE LO-TABLE
LDY DIV7HI,X
LDA MOD7HI,X
BPL GOTTAB ; BRANCH ALWAYS
LOTABLE LDY DIV7LO,X
LDA MOD7LO,X
GOTTAB TAX
LDA ANDMASK,X
STA ANDMSK
*
LDX YPOSN
LDA YLOOKLO,X
STA HBASL
LDA YLOOKHI,X
ORA G_PAGE
STA HBASL+1
LDA WIDEFLAG
BEQ NOTWIDE
JMP WIDEDOM
NOTWIDE JMP HORZLOOP
HRTS RTS
*
HNOROLL STA DIFF ; LOOP BOTTOM
HDECC DEC COUNT
BEQ HRTS
*
HORZLOOP LDA (HBASL),Y ; PLOT PIXEL
ORA ANDMSK ; SET ADDITIONAL POINTS
STA (HBASL),Y ; STORE POINTS
*
LDA ANDMSK ; MOVE RIGHT
ASL ; SHIFT & LOSE HI-BIT
EOR #$80 ; SET HI-BIT
BNE NOH8 ; IF HI-BIT IS CLEARED
INY ; NEXT BYTE
LDA #$81 ; RESET
NOH8 STA ANDMSK
*
LDA DIFF ; UPDATE ERROR DIFFERENCE
SEC
SBC DELTAY
BCS HNOROLL
ADC DELTAXL
STA DIFF
LHMODY INX ; MODIFYABLE
LDA YLOOKLO,X
STA HBASL
LDA YLOOKHI,X
ORA G_PAGE ; ACTIVE PAGE
STA HBASL+1
BNE HDECC
*
VERTDOM LDX YDRAW
CPX YPOSN
BNE ENDY0
LDX YTO
ENDY0 STX LVCHK+1
LDA DELTAY
LSR
STA DIFF
*
LDX XPOSL
LDA XPOSH
BEQ LOTABLL
LDY DIV7HI,X
LDA MOD7HI,X
BPL GOTTAB2
LOTABLL LDY DIV7LO,X
LDA MOD7LO,X
GOTTAB2 TAX
LDA ANDMASK,X
STA ANDMSK
LDX YPOSN
JMP VERTLOOP
*
VNOROLL STA DIFF
VERTLOOP LDA YLOOKLO,X
STA HBASL
LDA YLOOKHI,X
ORA G_PAGE
STA HBASL+1
LLMDV LDA (HBASL),Y ; PLOT PIXEL
ORA ANDMSK ; SET ADDITIONAL POINTS
STA (HBASL),Y ; STORE POINTS
LVCHK CPX #$00
BEQ VRTS
LVMODY INX
LDA DIFF
SEC
SBC DELTAXL
BCS VNOROLL
ADC DELTAY
STA DIFF
LDA ANDMSK ; MOVE RIGHT
ASL
EOR #$80
BEQ IS8
STA ANDMSK
BNE VERTLOOP
*
IS8 INY
LDA #$81
STA ANDMSK
BNE VERTLOOP
VRTS RTS
*
WIDEDOM LDA DELTAXH
STA COUNTH
LDX DELTAXL
STX COUNT
STX DIFF
LSR
ROR DIFF
STA DIFFH
LDX YPOSN
*
WIDELOOP LDA (HBASL),Y ; PLOT PIXEL
ORA ANDMSK ; SET ADDITIONAL POINTS
STA (HBASL),Y ; STORE POINTS
LDA ANDMSK
ASL
EOR #$80
BNE NOT7
INY
LDA #$81
NOT7 STA ANDMSK
*
LDA DIFF
SEC
SBC DELTAY
BCS WNOROLL
DEC DIFFH
BPL WNOROLL
ADC DELTAXL
STA DIFF
LDA DIFFH
ADC DELTAXH
STA DIFFH
LWMODY INX
LDA YLOOKLO,X
STA HBASL
LDA YLOOKHI,X
ORA G_PAGE
STA HBASL+1
BNE WDECC
*
WNOROLL STA DIFF
WDECC DEC COUNT
LDA COUNT
CMP #$FF
BNE WIDELOOP
DEC COUNTH
BEQ WIDELOOP
RTS
*
* PURE VERTICAL LINE
*
VERTLINE LDX YDRAW
LDY YTO
CPX YTO
BLT USEY0
TXA
TAY
LDX YTO
USEY0 STX YPOSN
INY
STY LPVYTEST+1
LDX XDRAW
LDA XDRAW+1
BEQ LOTABL2
LDY DIV7HI,X
LDA MOD7HI,X
BPL GOTIT
LOTABL2 LDY DIV7LO,X
LDA MOD7LO,X
GOTIT TAX
LDA ANDMASK,X
STA LPVAND+1
LDX YPOSN
*
PVERLOOP LDA YLOOKLO,X
STA HBASL
LDA YLOOKHI,X
ORA G_PAGE
STA HBASL+1
LLMDPV LDA (HBASL),Y
LPVAND ORA #$00 ; SELF-MODIFYING
STA (HBASL),Y
INX
LPVYTEST CPX #$00
BNE PVERLOOP
RTS
*
LST OFF
*
CHK
*
PLOT3D14.S - 3D-Demo Version 1.40
********************************
* 3D-DEMO *
* *
* BY MARC GOLOMBECK *
* *
* VERSION 1.40 / 25.04.2017 *
* *
* NEEDS THE FOLLOWING DATA *
* ALREADY LOADED INTO MEMORY: *
* *
* $7000: SINE/COSINE-TABLE *
* $7200: POINT AND LINE DATA *
* $7400: SHAPE TABLE *
* $7A00: MULTIPLICATION TABLE *
* $8200: PROJECTION TABLE *
* *
* CONTROLLED VIA JOYSTICK AND *
* KEYBOARD: *
* *
* PDL(0/1): ROTATION+ZOOM *
* PBN(0/1): RESET+STOP/EXIT *
* KEYS 1-5: CHOOSE 3D-OBJECT *
* KEYS +/-: ALTERNATE ZOOM *
* KEY B : TOGGLE BENCHMARK *
* KEY Q : QUIT PROGRAM *
* *
********************************
*
ORG $6000
*
HGR2 EQU $F3D8 ; SWITCH TO HIRES2
HGR EQU $F3E2 ; SWITCH TO HIRES1
HCLR EQU $F3F2 ; CLEAR HIRES SCREEN TO BLACK1
HCOLOR EQU $F6F0 ; SET HCOLOR
HPOSN EQU $F411 ; SET HIRES-CURSOR NO DRAW
HPLOT EQU $F457 ; DRAW HIRES-PIXEL
HLIN EQU $F53A ; DRAW HIRES-LINE
PREAD EQU $FB1E ; READ PADDLES
PB0 EQU $C061 ; PUSH-BUTTON 0
PB1 EQU $C062 ; PUSH-BUTTON 1
PB2 EQU $C063 ; PUSH-BUTTON 2
HOME EQU $FC58 ; CLEAR SCREEN
COUT EQU $FDED ; PRINT CHARACTER
KYBD EQU $C000 ; READ KEYBOARD
STROBE EQU $C010 ; CLEAR KEYBOARD
SHNUM EQU $F730 ; GET ADRESS OF SHAPE NUMBER
SHDRAW EQU $F605 ; DRAW SHAPE ON SCREEN
BELL EQU $FBDD ; RING BELL
WAIT EQU $FCA8 ; WAIT A BIT
*
SINTAB EQU $7000 ; BASE ADRESS OF SINE TABLE
COSTAB EQU $7040 ; BASE ADRESS OF COSINE TABLE
NUMPNT EQU $7200 ; NUMBER OF POINTS TO DRAW
TABLE EQU $7201 ; BASE ADRESS FOR POINT TABLE
SHTAB EQU $7400 ; BASE ADRESS OF SHAPES-68
SSQLO EQU $7A00 ; MULT TAB PART 1
SSQHI EQU $7C00 ; MULT TAB PART 2
DSQLO EQU $7E00 ; MULT TAB PART 3
DSQHI EQU $8000 ; MULT TAB PART 4
PROJTAB EQU $8200 ; PROJECTION TAB
*
XTRANS EQU $8B ; X-TRANSLATION CENTER SCREEN
YTRANS EQU $5F ; Y-TRANSLATION
ZTRANS EQU $FE ; MOVE 3D OBJECT AWAY FROM CAMERA
*
TXTPTR EQU $06 ; POINTER FOR TEXT OUTPUT
PTR EQU $08 ; POINTER FOR DOS COMMAND
PNTCNT EQU $09 ; WHICH POINT TO DRAW?
SCALE EQU $E7 ; SHAPE SCALE
SHTABPTR EQU $E8 ; POINTER TO SHAPE-TABLE
LOOPCNTY EQU $FA ; Y-ROT-COUNTER
ROTSPDY EQU $FB ; Y-ROTATIONAL SPEED
LOOPCNTX EQU $FC ; X-ROT-COUNTER
ROTSPDX EQU $FD ; X-ROTATIONAL SPEED
SCALING EQU $FF ; SCALING
XDRAW EQU $300 ; X-POSITION FOR DRAW
YDRAW EQU $302 ; Y-POSITION FOR DRAW
XDRAWO EQU $304 ; OLD POSITION X
YDRAWO EQU $306 ; OLD POSITION Y
XDRAW2 EQU $308 ; UNDRAW CURSOR X
YDRAW2 EQU $30A ; UNDRAW CURSOR Y
ASCR EQU $30B ; ACTIVE SCREEN TO DRAW
JOYCNT EQU $30C ; COUNTER FOR JOYSTICK REQUEST
BENCHM EQU $30D ; BENCHMARK ON?
MAXDRAW EQU $30E ; MAXIMUM LINES TO DRAW
TEMP1 EQU $EB ; TEMP STORAGE
TEMP2 EQU $EC ; TENP STORAGE
MKAND EQU $ED ; MULTIPLICANT
MATOR EQU $EF ; MULTIPLICATOR
*
PSLO EQU $D8 ; USING FAC-ADRESS RANGE
PSHI EQU $DA ; FOR POINTER IN MULT-TAB
PDLO EQU $DC ; USING ARG-ADRESS RANGE
PDHI EQU $DE ; FOR POINTER IN MULT-TAB
*
ENTRY JSR SETUP ; SETUP GRAPHIC & VARIABLES
*
TABLESET JSR WLCMTXT ; DRAW TOP & BOTTOM TEXT
*
INILOOP LDA #$00 ; INIT LOOP
STA LOOPCNTY ; CURRENT Y-STEP
LDA #$10
STA LOOPCNTX ; CURRENT X-STEP
*
* READ PADDELS
*
LOOP INC JOYCNT ; MAIN LOOP STARTS HERE
LDA JOYCNT
CMP #$04
BCC READ1 ; LESS THAN 2 CYCLES
LDA #$00 ; READ PADDLE EVERY 2 CYCLES
STA JOYCNT
*
PREAD0 LDX #$00 ; VARY Y-ROT SPEED
JSR PREAD ; PADDLE (0)
CPY #$64
BCC INCSPDY ; DECREASE SPEED
CPY #$9B
BCS DECSPDY ; INCREASE SPEED
BCC PREAD1 ; 256-STEP CIRCLE LOOP
*
DECSPDY LDA ROTSPDY ; DECREASE ANGLE
CMP #$02
BCC PREAD1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDY
DEC ROTSPDY
JMP PREAD1 ; JUMP TO NEXT COMMAND
INCSPDY LDA ROTSPDY ; DECREASE WAIT COUNTER
CMP #$20
BCS PREAD1 ; MAXIMUM 10
INC ROTSPDY
INC ROTSPDY
*
PREAD1 LDX #$01 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
BCC DECSPDX ; DECREASE SPEED
CPY #$9B
BCS INCSPDX ; INCREASE SPEED
BCC READ1 ; 256-STEP CIRCLE LOOP
*
DECSPDX LDA ROTSPDX ; DECREASE ANGLE
CMP #$02
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDX
DEC ROTSPDX
JMP READ1 ; JUMP TO NEXT COMMAND
INCSPDX LDA ROTSPDX ; DECREASE WAIT COUNTER
CMP #$20
BCS READ1 ; MAXIMUM 10
INC ROTSPDX
INC ROTSPDX
*
READ1 CLC ; CALC NEXT STEP
LDX #$00
LDA LOOPCNTY
BPL READ02
INX ; INIT FOR BENCHMARK
READ02 ADC ROTSPDY ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU -10
STA LOOPCNTY
LDA LOOPCNTY
BPL READ01 ;
INX
READ01 CPX #01
BNE READ03 ; BENCHMARK LOOP START
LDY BENCHM
BEQ READ03 ; BENCHMARK OFF
JSR BELL ; REING BELL
*
READ03 CLC
LDA LOOPCNTX
ADC ROTSPDX ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU - 10
STA LOOPCNTX
*
JSR INITPNTS ; CALC NEW POINT POSITIONS
JSR UDRWLNS ; UNDRAW LINES
*
* READ KEYBOARD FOR LOADING NEW OBJECTS
*
LDA KYBD
BPL NOKEY1 ; NO KEY IS PRESSED
KEY1 CMP #$B1 ; KEY '1' IS PRESSED
BNE KEY2
JSR LOAD1 ; LOAD OBJECT 1
JMP ENDKEY
KEY2 CMP #$B2 ; KEY '2' IS PRESSED
BNE KEY3
JSR LOAD2
JMP ENDKEY
KEY3 CMP #$B3 ; KEY '3' IS PRESSED
BNE KEY4
JSR LOAD3
JMP ENDKEY
KEY4 CMP #$B4 ; KEY '4' IS PRESSED
BNE KEY5
JSR LOAD4
JMP ENDKEY
KEY5 CMP #$B5 ; KEY '5' IS PRESSED
BNE KEYPLUS
JSR LOAD5
JMP ENDKEY
NOKEY1 BPL NOKEY ; INTERMEDIATE JUMP
KEYPLUS CMP #$AB ; KEY '+' IS PRESSED
BNE KEYMINUS
LDA STROBE
LDA ZTRANS ; INCREASE DISTANCE
CMP #$30 ; WAS $7F
BCC ENDKEY1 ; MAIXMUM 127
DEC ZTRANS
DEC ZTRANS
DEC ZTRANS
DEC ZTRANS
BNE ENDKEY1
KEYMINUS CMP #$AD ; KEY '-' IS PRESSED
BNE KEYQ
LDA STROBE
LDA ZTRANS ; DECREASE DISTANCE
CMP #$D0 ; WAS $43
BCS ENDKEY1 ; LOOPCNT STILL POSITIVE
INC ZTRANS
INC ZTRANS
INC ZTRANS
INC ZTRANS
BNE ENDKEY1 ; JUMP TO NEXT COMMAND
KEYQ CMP #$D1 ; KEY 'Q' IS PRESSED
BNE KEYB
LDA STROBE
JMP END ; END PROGRAM
KEYB CMP #$C2 ; KEY 'B' IS PRESSED
BNE NOKEY
LDA BENCHM ; TOGGLE BENCHMARK ON/OFF
BEQ BENCHON
DEC BENCHM ; TOGGLE OFF
BEQ ENDKEY1
BENCHON INC BENCHM ; TOGGLE ON
BNE ENDKEY1
ENDKEY JSR SETUP
JSR WLCMTXT ; WRITE TOP & BOTTOM TEXT
JSR INITPNTS ; SET INITIAL POINT POSITION
ENDKEY1 LDA STROBE ; CLEAR KEYPRESS
*
NOKEY JSR DRWLNS ; DRAW LINES
*
* CHECK PUSHBUTTONS
*
LDA PB1 ; PUSHBUTTON 1 PRESSED?
BMI END ; EXIT PROGRAM!
PB0CHK LDA PB0 ; PUSHBUTTON 0 PRESSED?
BPL GOLOOP ; NO -> DO NEXT LOOP
LDA #$00 ; RESET ASPECT AND STOP ROTATION
STA LOOPCNTX ; BACK TO INIT POS
STA LOOPCNTY
LDA #$0A
STA ROTSPDY ; STOP ROTATION
STA ROTSPDX
*
GOLOOP JMP LOOP ; START AGAIN
*
END LDA #$00 ; END PROGRAM
STA $C051 ; SWITCH TO TEXT
STA $C052
STA $C054
JSR HOME ; CLEAR SCREEN
JMP $03D0 ; DOS WARM START NO RTS HERE!
*
********************************
* SETUP GRAPHICS & DATA *
********************************
*
SETUP LDA #$00
STA $C050 ; SWITCH ON GRAPHICS
STA $C057 ; SWITCH TO HIRES
STA BENCHM ; BENCHMARK OFF
*
LDA #SHTAB
STA SHTABPTR+1
LDA #$01
STA SCALE ; SCALE = 1
*
LDA #32
STA $E6 ; DRAW ON 1
STA $C055 ; SHOW 2
JSR HCLR ; CLEAR HGR
JSR DRAWBOX ; DRAW BOX ON HIRES 1
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #64
STA $E6 ; DRAW ON 2
STA $C054
JSR HCLR ; CLEAR HGR2
JSR DRAWBOX ; DRAW BOX ON HIRES 2
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
LDX #11
LDY #01 ; XPOS = 267
LDA #09
JSR HPOSN
LDX #69
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #$03 ; INIT HCOLOR = 3
JSR HCOLOR
LDA #$0A
STA ROTSPDX ; INITIAL X-ROT SPEED = 0
LDA #$0F
STA ROTSPDY ; INITIAL Y-ROT SPEED = 1
*
LDA #$01
STA ASCR ; DRAW ON HIRES 1
STA JOYCNT ; SET JOYSTICK REQUEST COUNTER
*
LDA #$30 ; SCALING
STA SCALING
LDA #$50
STA ZTRANS ; MOVE OBJECT AWAY FROM CAMERA
*
LDA #SSQLO/256 ; SETUP MULT-TAB
STA PSLO+1
LDA #SSQHI/256
STA PSHI+1
LDA #DSQLO/256
STA PDLO+1
LDA #DSQHI/256
STA PDHI+1
*
LDA #$04
STA MAXDRAW ; NUMBER OF LINES TO DRAW
*
RTS
*
********************************
* DRAW LINES *
********************************
*
DRWLNS LDA #$00
STA PNTCNT
LDA ASCR
CMP #$01
BEQ DRWSCR1
BNE SETCLR
DRWSCR1 LDA #32
SETCLR LDX #$03 ; HCOLOR = 3
JSR HCOLOR
GETPNT2 LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX ; SKIP 3 BYTES
INX
INX
LDA TABLE,X ; GET XPOS LO-BYTE
STA XDRAW
INX
LDA TABLE,X ; GET XPOS HI-BYTE
STA XDRAW+1
INX
LDA TABLE,X ; GET YPOS
STA YDRAW
INX
INX ; SKIP 6 BYTES
INX
INX
INX
INX
INX
*
* EVALUATE POINTS TO DRAW TO
*
DRWNXT LDA TABLE,X
BEQ NXTPNT ; NOTHING MORE TO DRAW
TAY ; SUBTRACT 1 TO GET CORREC
DEY ; POINT NUMBER
TYA
ASL ; CALC BASE ADRESS OF POINT TO
ASL ; DRAW TO
ASL
ASL
TAY ; Y = POINNUMBER * 16
INY ; SKIP 3 BYTES
INY
INY
LDA TABLE,Y ; READ OUT POINTS TO DRAW TO
STA XTO
INY
LDA TABLE,Y
STA XTO+1
INY
LDA TABLE,Y
STA YTO
*
STX XREGSAVE ; SAVE X-REG ON STACK
LDX XDRAW
LDY XDRAW+1
LDA YDRAW
JSR HPOSN ; POSITION CURSOR
* JSR HPLOT ; POSITION CURSOR
LDA XTO
LDX XTO+1
LDY YTO
JSR HLIN ; DRAW LINE
* JSR WAIT
LDX XREGSAVE ; RESTORE X-REG
DEC MAXDRAW ; MAXIMUM NUMBER OF LINES
BEQ NXTPNT ; REACHED? IF YES NEXT POINT
INX ; INC X-REG TO NEXT POINT
BNE DRWNXT ; DRAW NEXT LINE
*
NXTPNT INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS DRWEND ; ALL DONE
JMP GETPNT2
DRWEND LDA ASCR ; DISPLAY DRAW-SCREEN
CMP #$02
BEQ DISP2 ; SHOW SCREEN 2
LDA #64
STA $E6 ; DRAW ON 2
STA $C054 ; SWITCH TO SCREEN1
INC ASCR ; ASCR = 2
BNE DRWEND2
DISP2 STA $C055 ; SWITCH TO SCREEN2
LDA #32
STA $E6 ; DRAW ON 1
DEC ASCR ; ASCR = 1
DRWEND2 RTS
*
XTO DS 2 ; DRAW TO X-POS
YTO DS 1 ; DRAW TO Y-POS
XREGSAVE DS 1 ; TEMPORARY SAVE FOR X-REG
*
*
********************************
* INIT POINT POSITIONS *
********************************
*
CYC ; PRINT CYCLES
*
INITPNTS LDA #$00
STA PNTCNT
*
* EVAL SIN/COS-TAB
*
LDX LOOPCNTX ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR X
STA SAX
LDA COSTAB,X ; GET COSINUS FOR X
STA CAX
LDX LOOPCNTY ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR Y
STA SAY
LDA COSTAB,X ; GET COSINUS FOR Y
STA CAY
LDA SAX ; SINXSINY = SINX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR FMULT ; FAST MULTIPLY
STY SINXSINY ; ONLY HI-BYTE
* LDA SAX ; SINXCOSY = SINX * COSY
* STA MATOR
LDA CAY
STA MKAND
JSR FMULT
STY SINXCOSY ; ONLY HI-BYTE
LDA CAX ; COSXSINY = COSX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR FMULT
STY COSXSINY
* LDA CAX ; COSXCOSY = COSX * COSY
* STA MATOR
LDA CAY
STA MKAND
JSR FMULT
STY COSXCOSY
LDA CAX ; COSXONE = COSX * $7F (= 1)
BPL CX1
TAY
DEY
TYA
EOR #$FF ; TWO'S COMPLEMENT
LSR
EOR #$FF
TAY
INY
STY COSXONE
BEQ SX1
BNE SX1
CX1 LSR ; SHORT METHOD IMPLEMENTED HERE
STA COSXONE ; DOES NOT NEED THE SMULT!
SX1 LDA SAX ; #SINXONE = SINX * $7F (= 1)
BPL SX10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINXONE
BEQ CY1
BNE CY1
SX10 LSR
STA SINXONE
CY1 LDA CAY ; COSYONE = COSX * $7F (= 1)
BPL CY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY COSYONE
BEQ SY1
BNE SY1
CY10 LSR
STA COSYONE
SY1 LDA SAY ; SINYONE = SINX * $7F (= 1)
BPL SY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINYONE
BEQ GETPNT
BNE GETPNT
SY10 LSR
STA SINYONE
*
*
* ROTATE POINTS AROUND X AND Y
*
GETPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
LDA TABLE,X ; GET XPOS
STA XPOS
INX
LDA TABLE,X ; GET YPOS
STA YPOS
INX
LDA TABLE,X ; GET ZPOS
STA ZPOS
*
STRTROT LDA XPOS ; RX = X * COS(Y) + Z * SIN(Y)
STA MATOR
LDA COSYONE
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA ZPOS
STA MATOR
LDA SINYONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
CLC ; ADD
LDA PX1
ADC PX2
STA RX
LDA PX1+1
ADC PX2+1
STA RX+1 ; SAVE HI-BYTE AS XPOS
*
* LDA ZPOS ; RZ = Z * C(X)C(Y) + Y * S(X) - X * C(X)S(Y)
* STA MATOR STILL IN MATOR
LDA COSXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA SINXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA XPOS
STA MATOR
LDA COSXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
CLC ; ADD
LDA PX1
ADC PX2
STA RZ
LDA PX1+1
ADC PX2+1
STA RZ+1
SEC ; SUB
LDA RZ
SBC PX3
STA RZ
LDA RZ+1
SBC PX3+1
CLC ; ADD ZTRANS
ADC ZTRANS
LSR
LSR
STA RZ+1
*
* ; RY = X * S(X)S(Y) + Y * C(X) - Z * S(X)C(Y)
* LDA XPOS STILL IN MATOR
* STA MATOR
LDA SINXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
LDA ZPOS ; RY = X * S(X)S(Y) + Y * C(X) - Z * S(X)C(Y)
STA MATOR
LDA SINXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA COSXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
CLC ; ADD
LDA PX3
ADC PX2
STA RY
LDA PX3+1
ADC PX2+1
STA RY+1
SEC ; SUB
LDA RY
SBC PX1
STA RY
LDA RY+1
SBC PX1+1
STA RY+1 ; SAVE HI-BYTE AS ZPOS
*
* PERFORM SCALING AND TRANSLATION
*
LDX RZ+1 ; LOAD PROJECTION
LDA PROJTAB,X
STA MATOR
LDA RX+1 ; ONLY HI-BYTE!
ASL
STA MKAND
JSR UMULT
STY QX
*
* LDA PROJTAB,X STILL IN MATOR!
LDA RY+1 ; ONLY HI-BYTE!
ASL
STA MKAND
JSR UMULT
STY QY
*
CLC ; XD = QX + XT
LDA QX
ADC #XTRANS
STA XD
LDA #$00
STA XD+1
LDA QX
BMI CALCYD ; IF QX < 0 THEN DO NOT ADD CARRY!
LDA #$00
ADC #$00 ; ADD CARRY BIT
STA XD+1
CALCYD CLC ; YD = QY + YT
LDA QY
ADC #YTRANS
STA YD ; ONLY 1 BYTE HERE, NO CARRY!
*
* WRITE DATA BACK TO TABLE
*
WRTPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX
INX
INX ; SKIP 3 BYTES
LDA XD ; SAVE XDRAW POSITION
STA TABLE,X
INX
LDA XD+1
STA TABLE,X
INX
LDA YD ; SAVE YDRAW POSITION
STA TABLE,X
*
INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS INITEND ; ALL DONE
JMP GETPNT
INITEND RTS
*
CYC OFF
*
XPOS DS 1
YPOS DS 1
ZPOS DS 1
XD DS 2
YD DS 2
SAX DS 1
CAX DS 1
SAY DS 1
CAY DS 1
PX1 DS 2 ; INTERMEDIATE RESULTS
PX2 DS 2
PX3 DS 2
RX DS 2
RY DS 2
RZ DS 2
SCX DS 2
SCY DS 2
QX DS 1
QY DS 1
SINXSINY DS 1
SINXCOSY DS 1
COSXSINY DS 1
COSXCOSY DS 1
COSXONE DS 1
SINXONE DS 1
COSYONE DS 1
SINYONE DS 1
DIVRES DS 1
PROJCORR DS 1
*
********************************
* DRAW BOX AROUND HIRES SCREEN *
********************************
*
DRAWBOX LDX #$03
JSR HCOLOR
LDA #$00
TAY
TAX
JSR HPLOT
LDA #23
LDX #01
JSR HLIN
*
LDA #23
LDX #01
LDY #$BF
JSR HLIN
*
LDA #$00
LDX #$00
LDY #$BF
JSR HLIN
*
LDA #$00
TAY
TAX
JSR HLIN
*
LDY #00
LDX #00
LDA #12
JSR HPOSN
*
LDA #23
LDX #01
LDY #12
JSR HLIN
RTS
*
********************************
*SIGNED DIVISION 16 BIT/8 BIT *
********************************
*
CYC
*
DIVI STY DEND ;
STA DEND+1
STX DOR
*
LDX #$00
DECHK LDA DEND+1 ; DIVIDEND NEG?
BPL DORCHK
INX ; INC X-REG FOR NEG SIGN
LDA DEND
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DEND
LDA DEND+1
SBC #$00
EOR #$FF
STA DEND+1
DORCHK LDA DOR ; DIVISOR NEG?
BPL DIVIGO
INX ; INC X-REG FOR NEG SIGN
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DOR
*
DIVIGO LDA DEND+1 ; TOO LARGE OR ZERO?
CMP DOR ; CMP HI-BYTE WITH DOR!
BCC DLOOP ; NO -> NO ERROR!
JMP DIVERR ; YES -> ERROR!
DLOOP ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP2
DSUBTR SBC DOR
INC DEND
DLOOP2 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR2 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP3
DSUBTR2 SBC DOR
INC DEND
DLOOP3 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR3 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP4
DSUBTR3 SBC DOR
INC DEND
DLOOP4 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR4 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP5
DSUBTR4 SBC DOR
INC DEND
DLOOP5 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR5 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP6
DSUBTR5 SBC DOR
INC DEND
DLOOP6 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR6 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP7
DSUBTR6 SBC DOR
INC DEND
DLOOP7 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR7 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP8
DSUBTR7 SBC DOR
INC DEND
DLOOP8 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR8 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DCONT
DSUBTR8 SBC DOR
INC DEND
*
* STORE RESULTS
*
DCONT STA DOR ; MOVE REMAINDER IN DOR
CLC ; NO ERROR -> CLEAR CARRY
CPX #$01 ; NEG SIGN FOR RESULT?
BNE DIVEND ; NO, SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA DOR
LDA DEND
EOR #$FF
ADC #$01
STA DEND
LDA DOR ; DOR = REMAINDER
DIVEND LDY DEND ; DEND = QUOTIENT
BNE DIVRTS
INY
DIVRTS RTS
DIVERR LDY #$00 ; RETURN 0 AS RESULT
RTS
*
CYC OFF
*
DEND DS 2
DOR DS 1
*
********************************
* 8-BIT UNSIGNED FAST MULTIPLY *
********************************
*
CYC
*
UMULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
UMTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSHI
EOR #$FF
STA PDHI
SEC
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL UMDONE ; NO -> ALL DONE
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
UMDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
RTS
*
CYC OFF
*
*
********************************
* 8-BIT SIGNED COMPL MULTIPLY *
********************************
*
CYC
*
MULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
MTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSLO ; INDEX INTO SUM TABLE BY A
STA PSHI
EOR #$FF
STA PDLO ; INDEX INTO DIFF TABLE BY -A-1
STA PDHI
LDA (PSLO),Y ; GET (A+Y)^2/4 (LO BYTE)
SEC
SBC (PDLO),Y ; SUBTRACT (-A+Y)^2/4 (LO BYTE)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL CHKT2 ; NO CHECK MATOR
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
CHKT2 LDY TEMP2 ; CHECK IF MATOR < 0
BPL MDONE ; NO, RTS
SEC ; MATOR STILL IN ACCU
SBC TEMP1 ; SUBTRACT TEMP1 FROM MATOR
*
MDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
LDA MKAND ; LOAD LO BYTE
RTS
*
CYC OFF
*
********************************
* 8-BIT SIGNED FAST MULTIPLY *
********************************
*
CYC
*
FMULT LDY MKAND
STY TEMP1 ; SAVE FOR LATER USE
FMTCHK LDA MATOR
STA TEMP2 ; SAVE FOR LATER USE
STA PSHI
EOR #$FF
STA PDHI
SEC
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
*
* STORE RESULTS
*
LDY TEMP1 ; CHECK IF MKAND < 0
BPL FCHKT2 ; NO CHECK MATOR
SEC ; MATOR STILL IN ACCU!
SBC TEMP2 ; SUBTRACT TEMP2 FROM MATOR
*
FCHKT2 LDY TEMP2 ; CHECK IF MATOR < 0
BPL FMDONE ; NO, RTS
SEC ; MATOR STILL IN ACCU
SBC TEMP1 ; SUBTRACT TEMP1 FROM MATOR
*
FMDONE TAY ; MOVE ACCU TO Y-REG AS RESULT
RTS
*
CYC OFF
*
********************************
* TOP & BOTTOM TEXT MESSAGE *
********************************
*
* PRINT OUT WELCOME TEXT AS SHAPES ON SCREEN
*
WLCMTXT LDX #$03
JSR HCOLOR
STX $F9 ; SET ROT = 0
LDA #$01
STA SCALE ; SET SCALE = 1
LDX #$00
TXTLOOP LDA TXTDAT,X
BEQ TLP2 ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #26 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX XREGDUMP
INX
BNE TXTLOOP
*
TLP2 LDX #$00
TXTLOOP2 LDA TXTDAT2,X
BEQ SUDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
LDX XREGDUMP
INX
BNE TXTLOOP2
SUDONE RTS
*
* TEXT MESSAGES WHEN LOADING 3D-OBJECTS
*
TXTOB1 LDA #TXTDAT3
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB2 LDA #TXTDAT4
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB3 LDA #TXTDAT5
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB4 LDA #TXTDAT6
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB5 LDA #TXTDAT7
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
PRTTXT LDY #$00
LDX #$03
JSR HCOLOR ; SET HCOLOR = 3
TXTLOOP3 LDA (TXTPTR),Y
BEQ TXTDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STY YREGDUMP ; SAVE X-REG COUNTER STATUS
TYA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAY ; MOVE X-POS TO Y-REG
TAX ; ALSO TO X-REG
STY SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDY YREGDUMP
INY
BNE TXTLOOP3
TXTDONE RTS
*
TXTDAT HEX 292231313A01151135
HEX 2901232A33352925223A
HEX 012231312D26013E3C
HEX 00
*
TXTDAT2 HEX 450114250E25262E3001
HEX 0E012E0F28302D30
HEX 2E2326242C01131112
HEX 18014500
*
TXTDAT3 HEX 2D3022252A2F28013529
HEX 2601352635332226252633
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT4 HEX 2D3022252A2F28013529
HEX 2601362E2333262D2D22
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT5 HEX 2D3022252A2F28013529
HEX 2601342A2E312D260124362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT6 HEX 2D3022252A2F28013529
HEX 2601352635332224362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT7 HEX 2D3022252A2F28013529
HEX 2601243623260135382A2F34
HEX 0F0F0F010101010101
HEX 010100
*
LCNT DS 1
XREGDUMP DS 1
YREGDUMP DS 1
SHPDUMP DS 1
SHXPOS DS 1
*
* DELETE BOTTOM TEXT
*
DLTTXT LDX #$00
JSR HCOLOR ; HCOLOR = 0
LDA ASCR
DLTSTRT LDA #180
STA YDELROW ; Y OF LINE TO DELETE
DLTLOOP LDA #32
STA $E6 ; DELETE ON SCREEN 1
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
LDA #64
STA $E6 ; DELETE ON SCREEN 2
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
INC YDELROW
LDA YDELROW
CMP #189 ; LINE 189 REACHED?
BCC DLTLOOP ; NO -> DELETE NEXT LINE
DLTEND RTS ; END OF LOOP
*
YDELROW DS 1
*
********************************
* LOAD 3D-OBJECTS IN MEMORY *
********************************
*
LOAD1 JSR TXTOB1 ; PRINT LOADING MESSAGE
LOAD01 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT1.3D,A$7200"
HEX 8D00
RTS
*
LOAD2 JSR TXTOB2
LOAD02 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT2.3D,A$7200"
HEX 8D00
RTS
*
LOAD3 JSR TXTOB3
LOAD03 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT3.3D,A$7200"
HEX 8D00
RTS
*
LOAD4 JSR TXTOB4
LOAD04 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT4.3D,A$7200"
HEX 8D00
RTS
*
LOAD5 JSR TXTOB5
LOAD05 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT5.3D,A$7200"
HEX 8D00
RTS
*
PRINT PLA
STA PTR
PLA
STA PTR+1
LDY #$01
P0 LDA (PTR),Y
BEQ PFIN
JSR COUT
INY
BNE P0
CHK
*
PFIN CLC
TYA
ADC PTR
STA PTR
LDA PTR+1
ADC #$00
PHA
LDA PTR
PHA
PEXIT RTS
*
********************************
* UNDRAW LINES *
********************************
*
UDRWLNS LDA #$00
*
LDY $E6
CPY #$20
BEQ UDRWSCR1
JMP UDRWSCR2
UDRWSCR1 LDX #$0B
UDRWLP1 STA $2200,X
STA $2600,X
STA $2A00,X
STA $2E00,X
STA $3200,X
STA $3600,X
STA $3A00,X
STA $3E00,X
STA $2280,X
STA $2680,X
STA $2A80,X
STA $2E80,X
STA $3280,X
STA $3680,X
STA $3A80,X
STA $3E80,X
STA $2300,X
STA $2700,X
STA $2B00,X
STA $2F00,X
STA $3300,X
STA $3700,X
STA $3B00,X
STA $3F00,X
STA $2380,X
STA $2780,X
STA $2B80,X
STA $2F80,X
STA $3380,X
STA $3780,X
STA $3B80,X
STA $3F80,X
STA $2028,X
STA $2428,X
STA $2828,X
STA $2C28,X
STA $3028,X
STA $3428,X
STA $3828,X
STA $3C28,X
STA $20A8,X
STA $24A8,X
STA $28A8,X
STA $2CA8,X
STA $30A8,X
STA $34A8,X
STA $38A8,X
STA $3CA8,X
STA $2128,X
STA $2528,X
STA $2928,X
STA $2D28,X
STA $3128,X
STA $3528,X
STA $3928,X
STA $3D28,X
STA $21A8,X
STA $25A8,X
STA $29A8,X
STA $2DA8,X
STA $31A8,X
STA $35A8,X
STA $39A8,X
STA $3DA8,X
STA $2228,X
STA $2628,X
STA $2A28,X
STA $2E28,X
STA $3228,X
STA $3628,X
STA $3A28,X
STA $3E28,X
STA $22A8,X
STA $26A8,X
STA $2AA8,X
STA $2EA8,X
STA $32A8,X
STA $36A8,X
STA $3AA8,X
STA $3EA8,X
STA $2328,X
STA $2728,X
STA $2B28,X
STA $2F28,X
STA $3328,X
STA $3728,X
STA $3B28,X
STA $3F28,X
STA $23A8,X
STA $27A8,X
STA $2BA8,X
STA $2FA8,X
STA $33A8,X
STA $37A8,X
STA $3BA8,X
STA $3FA8,X
*
STA $2050,X
STA $2450,X
STA $2850,X
STA $2C50,X
STA $3050,X
STA $3450,X
STA $3850,X
STA $3C50,X
STA $20D0,X
STA $24D0,X
STA $28D0,X
STA $2CD0,X
STA $30D0,X
STA $34D0,X
STA $38D0,X
STA $3CD0,X
STA $2150,X
STA $2550,X
STA $2950,X
STA $2D50,X
STA $3150,X
STA $3550,X
STA $3950,X
STA $3D50,X
STA $21D0,X
STA $25D0,X
STA $29D0,X
STA $2DD0,X
STA $31D0,X
STA $35D0,X
STA $39D0,X
STA $3DD0,X
INX
CPX #29
BEQ UDRW1RTS
JMP UDRWLP1
UDRW1RTS RTS
UDRWSCR2 LDX #$0B
UDRWLP2 STA $4200,X
STA $4600,X
STA $4A00,X
STA $4E00,X
STA $5200,X
STA $5600,X
STA $5A00,X
STA $5E00,X
STA $4280,X
STA $4680,X
STA $4A80,X
STA $4E80,X
STA $5280,X
STA $5680,X
STA $5A80,X
STA $5E80,X
STA $4300,X
STA $4700,X
STA $4B00,X
STA $4F00,X
STA $5300,X
STA $5700,X
STA $5B00,X
STA $5F00,X
STA $4380,X
STA $4780,X
STA $4B80,X
STA $4F80,X
STA $5380,X
STA $5780,X
STA $5B80,X
STA $5F80,X
STA $4028,X
STA $4428,X
STA $4828,X
STA $4C28,X
STA $5028,X
STA $5428,X
STA $5828,X
STA $5C28,X
STA $40A8,X
STA $44A8,X
STA $48A8,X
STA $4CA8,X
STA $50A8,X
STA $54A8,X
STA $58A8,X
STA $5CA8,X
*
STA $4128,X
STA $4528,X
STA $4928,X
STA $4D28,X
STA $5128,X
STA $5528,X
STA $5928,X
STA $5D28,X
STA $41A8,X
STA $45A8,X
STA $49A8,X
STA $4DA8,X
STA $51A8,X
STA $55A8,X
STA $59A8,X
STA $5DA8,X
STA $4228,X
STA $4628,X
STA $4A28,X
STA $4E28,X
STA $5228,X
STA $5628,X
STA $5A28,X
STA $5E28,X
STA $42A8,X
STA $46A8,X
STA $4AA8,X
STA $4EA8,X
STA $52A8,X
STA $56A8,X
STA $5AA8,X
STA $5EA8,X
STA $4328,X
STA $4728,X
STA $4B28,X
STA $4F28,X
STA $5328,X
STA $5728,X
STA $5B28,X
STA $5F28,X
STA $43A8,X
STA $47A8,X
STA $4BA8,X
STA $4FA8,X
STA $53A8,X
STA $57A8,X
STA $5BA8,X
STA $5FA8,X
*
STA $4050,X
STA $4450,X
STA $4850,X
STA $4C50,X
STA $5050,X
STA $5450,X
STA $5850,X
STA $5C50,X
STA $40D0,X
STA $44D0,X
STA $48D0,X
STA $4CD0,X
STA $50D0,X
STA $54D0,X
STA $58D0,X
STA $5CD0,X
STA $4150,X
STA $4550,X
STA $4950,X
STA $4D50,X
STA $5150,X
STA $5550,X
STA $5950,X
STA $5D50,X
STA $41D0,X
STA $45D0,X
STA $49D0,X
STA $4DD0,X
STA $51D0,X
STA $55D0,X
STA $59D0,X
STA $5DD0,X
INX
CPX #29
BEQ UDRW2RTS
JMP UDRWLP2
UDRW2RTS RTS
*
LST OFF
*
CHK
*
PLOT3D13.S - 3D-Demo Version 1.31
********************************
* 3D-DEMO *
* *
* BY MARC GOLOMBECK *
* *
* VERSION 1.31 / 19.04.2017 *
* *
* NEEDS THE FOLLOWING DATA *
* ALREADY LOADED INTO MEMORY: *
* *
* $7000: SINE/COSINE-TABLE *
* $7200: POINT AND LINE DATA *
* $7400: SHAPE TABLE *
* $7A00: MULTIPLICATION TABLE *
* *
* CONTROLLED VIA JOYSTICK AND *
* KEYBOARD: *
* *
* PDL(0/1): ROTATION+ZOOM *
* PBN(0/1): RESET+STOP/EXIT *
* KEYS 1-5: CHOOSE 3D-OBJECT *
* KEYS +/-: ALTERNATE ZOOM *
* KEY B : TOGGLE BENCHMARK *
* KEY Q : QUIT PROGRAM *
* *
********************************
*
ORG $6000
*
HGR2 EQU $F3D8 ; SWITCH TO HIRES2
HGR EQU $F3E2 ; SWITCH TO HIRES1
HCLR EQU $F3F2 ; CLEAR HIRES SCREEN TO BLACK1
HCOLOR EQU $F6F0 ; SET HCOLOR
HPOSN EQU $F411 ; SET HIRES-CURSOR NO DRAW
HPLOT EQU $F457 ; DRAW HIRES-PIXEL
HLIN EQU $F53A ; DRAW HIRES-LINE
PREAD EQU $FB1E ; READ PADDLES
PB0 EQU $C061 ; PUSH-BUTTON 0
PB1 EQU $C062 ; PUSH-BUTTON 1
PB2 EQU $C063 ; PUSH-BUTTON 2
HOME EQU $FC58 ; CLEAR SCREEN
COUT EQU $FDED ; PRINT CHARACTER
KYBD EQU $C000 ; READ KEYBOARD
STROBE EQU $C010 ; CLEAR KEYBOARD
SHNUM EQU $F730 ; GET ADRESS OF SHAPE NUMBER
SHDRAW EQU $F605 ; DRAW SHAPE ON SCREEN
BELL EQU $FBDD ; RING BELL
*
SINTAB EQU $7000 ; BASE ADRESS OF SINE TABLE
COSTAB EQU $7040 ; BASE ADRESS OF COSINE TABLE
NUMPNT EQU $7200 ; NUMBER OF POINTS TO DRAW
TABLE EQU $7201 ; BASE ADRESS FOR POINT TABLE
SHTAB EQU $7400 ; BASE ADRESS OF SHAPES-68
SSQLO EQU $7A00 ; MULT TAB PART 1
SSQHI EQU $7C00 ; MULT TAB PART 2
DSQLO EQU $7E00 ; MULT TAB PART 3
DSQHI EQU $8000 ; MULT TAB PART 4
*
XTRANS EQU $8B ; X-TRANSLATION CENTER SCREEN
YTRANS EQU $5F ; Y-TRANSLATION
ZTRANS EQU $FE ; MOVE 3D OBJECT AWAY FROM CAMERA
*
TXTPTR EQU $06 ; POINTER FOR TEXT OUTPUT
PTR EQU $08 ; POINTER FOR DOS COMMAND
PNTCNT EQU $09 ; WHICH POINT TO DRAW?
SCALE EQU $E7 ; SHAPE SCALE
SHTABPTR EQU $E8 ; POINTER TO SHAPE-TABLE
LOOPCNTY EQU $FA ; Y-ROT-COUNTER
ROTSPDY EQU $FB ; Y-ROTATIONAL SPEED
LOOPCNTX EQU $FC ; X-ROT-COUNTER
ROTSPDX EQU $FD ; X-ROTATIONAL SPEED
SCALING EQU $FF ; SCALING
XDRAW EQU $300 ; X-POSITION FOR DRAW
YDRAW EQU $302 ; Y-POSITION FOR DRAW
XDRAWO EQU $304 ; OLD POSITION X
YDRAWO EQU $306 ; OLD POSITION Y
XDRAW2 EQU $308 ; UNDRAW CURSOR X
YDRAW2 EQU $30A ; UNDRAW CURSOR Y
ASCR EQU $30B ; ACTIVE SCREEN TO DRAW
JOYCNT EQU $30C ; COUNTER FOR JOYSTICK REQUEST
BENCHM EQU $30D ; BENCHMARK ON?
MAXDRAW EQU $30E ; MAXIMUM LINES TO DRAW
*
PSLO EQU $D8 ; USING FAC-ADRESS RANGE
PSHI EQU $DA ; FOR POINTER IN MULT-TAB
PDLO EQU $DC ; USING ARG-ADRESS RANGE
PDHI EQU $DE ; FOR POINTER IN MULT-TAB
*
ENTRY JSR SETUP ; SETUP GRAPHIC & VARIABLES
*
TABLESET JSR WLCMTXT ; DRAW TOP & BOTTOM TEXT
*
INILOOP LDA #$00 ; INIT LOOP
STA LOOPCNTY ; CURRENT Y-STEP
LDA #$10
STA LOOPCNTX ; CURRENT X-STEP
*
* READ PADDELS
*
LOOP INC JOYCNT ; MAIN LOOP STARTS HERE
LDA JOYCNT
CMP #$02
BCC READ1 ; LESS THAN 2 CYCLES
LDA #$00 ; READ PADDLE EVERY 2 CYCLES
STA JOYCNT
*
PREAD0 LDX #$00 ; VARY Y-ROT SPEED
JSR PREAD ; PADDLE (0)
CPY #$64
BCC INCSPDY ; DECREASE SPEED
CPY #$9B
BCS DECSPDY ; INCREASE SPEED
BCC PREAD1 ; 256-STEP CIRCLE LOOP
*
DECSPDY LDA ROTSPDY ; DECREASE ANGLE
CMP #$01
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDY
JMP PREAD1 ; JUMP TO NEXT COMMAND
INCSPDY LDA ROTSPDY ; DECREASE WAIT COUNTER
CMP #$20
BCS PREAD1 ; MAXIMUM 10
INC ROTSPDY
*
PREAD1 LDX #$01 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
BCC DECSPDX ; DECREASE SPEED
CPY #$9B
BCS INCSPDX ; INCREASE SPEED
BCC READ1 ; 256-STEP CIRCLE LOOP
*
DECSPDX LDA ROTSPDX ; DECREASE ANGLE
CMP #$01
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDX
JMP READ1 ; JUMP TO NEXT COMMAND
INCSPDX LDA ROTSPDX ; DECREASE WAIT COUNTER
CMP #$20
BCS READ1 ; MAXIMUM 10
INC ROTSPDX
*
*
PREAD2 LDX #$02 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
* BCC DECZTRS ; DECREASE SPEED
CPY #$9B
* BCS INCZTRS ; INCREASE SPEED
BCC READ1 ; 256-STEP CIRCLE LOOP
*
*
READ1 CLC ; CALC NEXT STEP
LDX #$00
LDA LOOPCNTY
BPL READ02
INX ; INIT FOR BENCHMARK
READ02 ADC ROTSPDY ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU -10
STA LOOPCNTY
LDA LOOPCNTY
BPL READ01 ;
INX
READ01 CPX #01
BNE READ03 ; BENCHMARK LOOP START
LDY BENCHM
BEQ READ03 ; BENCHMARK OFF
JSR BELL ; REING BELL
*
READ03 CLC
LDA LOOPCNTX
ADC ROTSPDX ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU - 10
STA LOOPCNTX
*
JSR INITPNTS ; CALC NEW POINT POSITIONS
JSR UDRWLNS ; UNDRAW LINES
*
* READ KEYBOARD FOR LOADING NEW OBJECTS
*
LDA KYBD
BPL NOKEY1 ; NO KEY IS PRESSED
KEY1 CMP #$B1 ; KEY '1' IS PRESSED
BNE KEY2
JSR LOAD1 ; LOAD OBJECT 1
JMP ENDKEY
KEY2 CMP #$B2 ; KEY '2' IS PRESSED
BNE KEY3
JSR LOAD2
JMP ENDKEY
KEY3 CMP #$B3 ; KEY '3' IS PRESSED
BNE KEY4
JSR LOAD3
JMP ENDKEY
KEY4 CMP #$B4 ; KEY '4' IS PRESSED
BNE KEY5
JSR LOAD4
JMP ENDKEY
KEY5 CMP #$B5 ; KEY '5' IS PRESSED
BNE KEYPLUS
JSR LOAD5
JMP ENDKEY
NOKEY1 BPL NOKEY ; INTERMEDIATE JUMP
KEYPLUS CMP #$AB ; KEY '+' IS PRESSED
BNE KEYMINUS
LDA STROBE
LDA SCALING ; INCREASE DISTANCE
CMP #$B7 ; WAS $7F
BCS ENDKEY1 ; MAIXMUM 127
INC SCALING
INC SCALING
INC SCALING
INC SCALING
BNE ENDKEY1
KEYMINUS CMP #$AD ; KEY '-' IS PRESSED
BNE KEYQ
LDA STROBE
LDA SCALING ; DECREASE DISTANCE
CMP #$0A ; WAS $43
BCC ENDKEY1 ; LOOPCNT STILL POSITIVE
DEC SCALING
DEC SCALING
DEC SCALING
DEC SCALING
BNE ENDKEY1 ; JUMP TO NEXT COMMAND
KEYQ CMP #$D1 ; KEY 'Q' IS PRESSED
BNE KEYB
LDA STROBE
JMP END ; END PROGRAM
KEYB CMP #$C2 ; KEY 'B' IS PRESSED
BNE NOKEY
LDA BENCHM ; TOGGLE BENCHMARK ON/OFF
BEQ BENCHON
DEC BENCHM ; TOGGLE OFF
BEQ ENDKEY1
BENCHON INC BENCHM ; TOGGLE ON
BNE ENDKEY1
ENDKEY JSR SETUP
JSR WLCMTXT ; WRITE TOP & BOTTOM TEXT
JSR INITPNTS ; SET INITIAL POINT POSITION
ENDKEY1 LDA STROBE ; CLEAR KEYPRESS
*
NOKEY JSR DRWLNS ; DRAW LINES
*
* CHECK PUSHBUTTONS
*
LDA PB1 ; PUSHBUTTON 1 PRESSED?
BMI END ; EXIT PROGRAM!
PB0CHK LDA PB0 ; PUSHBUTTON 0 PRESSED?
BPL GOLOOP ; NO -> DO NEXT LOOP
LDA #$00 ; RESET ASPECT AND STOP ROTATION
STA LOOPCNTX ; BACK TO INIT POS
STA LOOPCNTY
LDA #$0A
STA ROTSPDY ; STOP ROTATION
STA ROTSPDX
*
GOLOOP JMP LOOP ; START AGAIN
*
END LDA #$00 ; END PROGRAM
STA $C051 ; SWITCH TO TEXT
STA $C052
STA $C054
JSR HOME ; CLEAR SCREEN
JMP $03D0 ; DOS WARM START NO RTS HERE!
*
********************************
* SETUP GRAPHICS & DATA *
********************************
*
SETUP LDA #$00
STA $C050 ; SWITCH ON GRAPHICS
STA $C057 ; SWITCH TO HIRES
STA BENCHM ; BENCHMARK OFF
*
LDA #SHTAB
STA SHTABPTR+1
LDA #$01
STA SCALE ; SCALE = 1
*
LDA #32
STA $E6 ; DRAW ON 1
STA $C055 ; SHOW 2
JSR HCLR ; CLEAR HGR
JSR DRAWBOX ; DRAW BOX ON HIRES 1
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #64
STA $E6 ; DRAW ON 2
STA $C054
JSR HCLR ; CLEAR HGR2
JSR DRAWBOX ; DRAW BOX ON HIRES 2
LDX #14
LDY #01 ; XPOS = 270
LDA #6
JSR HPOSN
LDX #67
JSR SHNUM
LDA #00
JSR SHDRAW
LDX #11
LDY #01 ; XPOS = 267
LDA #09
JSR HPOSN
LDX #69
JSR SHNUM
LDA #00
JSR SHDRAW
*
LDA #$03 ; INIT HCOLOR = 3
JSR HCOLOR
LDA #$0A
STA ROTSPDX ; INITIAL X-ROT SPEED = 0
LDA #$0F
STA ROTSPDY ; INITIAL Y-ROT SPEED = 1
*
LDA #$01
STA ASCR ; DRAW ON HIRES 1
STA JOYCNT ; SET JOYSTICK REQUEST COUNTER
*
LDA #$90 ; SCALING
STA SCALING
LDA #$50
STA ZTRANS ; MOVE OBJECT AWAY FROM CAMERA
*
LDA #SSQLO/256 ; SETUP MULT-TAB
STA PSLO+1
LDA #SSQHI/256
STA PSHI+1
LDA #DSQLO/256
STA PDLO+1
LDA #DSQHI/256
STA PDHI+1
*
LDA #$04
STA MAXDRAW ; NUMBER OF LINES TO DRAW
*
RTS
*
********************************
* DRAW LINES *
********************************
*
DRWLNS LDA #$00
STA PNTCNT
LDA ASCR
CMP #$01
BEQ DRWSCR1
BNE SETCLR
DRWSCR1 LDA #32
SETCLR LDX #$03 ; HCOLOR = 3
JSR HCOLOR
GETPNT2 LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX ; SKIP 3 BYTES
INX
INX
LDA TABLE,X ; GET XPOS LO-BYTE
STA XDRAW
INX
LDA TABLE,X ; GET XPOS HI-BYTE
STA XDRAW+1
INX
LDA TABLE,X ; GET YPOS
STA YDRAW
INX
INX ; SKIP 6 BYTES
INX
INX
INX
INX
INX
*
* EVALUATE POINTS TO DRAW TO
*
DRWNXT LDA TABLE,X
BEQ NXTPNT ; NOTHING MORE TO DRAW
TAY ; SUBTRACT 1 TO GET CORREC
DEY ; POINT NUMBER
TYA
ASL ; CALC BASE ADRESS OF POINT TO
ASL ; DRAW TO
ASL
ASL
TAY ; Y = POINNUMBER * 16
INY ; SKIP 3 BYTES
INY
INY
LDA TABLE,Y ; READ OUT POINTS TO DRAW TO
STA XTO
INY
LDA TABLE,Y
STA XTO+1
INY
LDA TABLE,Y
STA YTO
*
STX XREGSAVE ; SAVE X-REG ON STACK
LDX XDRAW
LDY XDRAW+1
LDA YDRAW
JSR HPOSN ; POSITION CURSOR
LDA XTO
LDX XTO+1
LDY YTO
JSR HLIN ; DRAW LINE
LDX XREGSAVE ; RESTORE X-REG
DEC MAXDRAW ; MAXIMUM NUMBER OF LINES
BEQ NXTPNT ; REACHED? IF YES NEXT POINT
INX ; INC X-REG TO NEXT POINT
BNE DRWNXT ; DRAW NEXT LINE
*
NXTPNT INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS DRWEND ; ALL DONE
JMP GETPNT2
DRWEND LDA ASCR ; DISPLAY DRAW-SCREEN
CMP #$02
BEQ DISP2 ; SHOW SCREEN 2
LDA #64
STA $E6 ; DRAW ON 2
STA $C054 ; SWITCH TO SCREEN1
INC ASCR ; ASCR = 2
BNE DRWEND2
DISP2 STA $C055 ; SWITCH TO SCREEN2
LDA #32
STA $E6 ; DRAW ON 1
DEC ASCR ; ASCR = 1
DRWEND2 RTS
*
XTO DS 2 ; DRAW TO X-POS
YTO DS 1 ; DRAW TO Y-POS
XREGSAVE DS 1 ; TEMPORARY SAVE FOR X-REG
*
*
********************************
* INIT POINT POSITIONS *
********************************
*
CYC ; PRINT CYCLES
*
INITPNTS LDA #$00
STA PNTCNT
*
* EVAL SIN/COS-TAB
*
LDX LOOPCNTX ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR X
STA SAX
LDA COSTAB,X ; GET COSINUS FOR X
STA CAX
LDX LOOPCNTY ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR Y
STA SAY
LDA COSTAB,X ; GET COSINUS FOR Y
STA CAY
LDA SAX ; SINXSINY = SINX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR MULT
STY SINXSINY ; ONLY HI-BYTE
LDA SAX ; SINXCOSY = SINX * COSY
STA MATOR
LDA CAY
STA MKAND
JSR MULT
STY SINXCOSY ; ONLY HI-BYTE
LDA CAX ; COSXSINY = COSX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR MULT
STY COSXSINY
LDA CAX ; COSXCOSY = COSX * COSY
STA MATOR
LDA CAY
STA MKAND
JSR MULT
STY COSXCOSY
LDA CAX ; COSXONE = COSX * $7F (= 1)
BPL CX1
TAY
DEY
TYA
EOR #$FF ; TWO'S COMPLEMENT
LSR
EOR #$FF
TAY
INY
STY COSXONE
BEQ SX1
BNE SX1
CX1 LSR ; SHORT METHOD IMPLEMENTED HERE
STA COSXONE ; DOES NOT NEED THE SMULT!
SX1 LDA SAX ; SINXONE = SINX * $7F (= 1)
BPL SX10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINXONE
BEQ CY1
BNE CY1
SX10 LSR
STA SINXONE
CY1 LDA CAY ; COSYONE = COSX * $7F (= 1)
BPL CY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY COSYONE
BEQ SY1
BNE SY1
CY10 LSR
STA COSYONE
SY1 LDA SAY ; SINYONE = SINX * $7F (= 1)
BPL SY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINYONE
BEQ GETPNT
BNE GETPNT
SY10 LSR
STA SINYONE
*
*
* ROTATE POINTS AROUND X AND Y
*
GETPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
LDA TABLE,X ; GET XPOS
STA XPOS
INX
LDA TABLE,X ; GET YPOS
STA YPOS
INX
LDA TABLE,X ; GET ZPOS
STA ZPOS
*
STRTROT LDA XPOS ; RX = X * COS(Y) + Z * SIN(Y)
STA MATOR
LDA COSYONE
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA ZPOS
STA MATOR
LDA SINYONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
CLC ; ADD
LDA PX1
ADC PX2
STA RX
LDA PX1+1
ADC PX2+1
STA RX+1 ; SAVE HI-BYTE AS XPOS
*
LDA ZPOS ; RZ = Z * C(X)C(Y) + Y * S(X) - X * C(X)S(Y)
STA MATOR
LDA COSXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA SINXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA XPOS
STA MATOR
LDA COSXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
CLC ; ADD
LDA PX1
ADC PX2
STA RZ
LDA PX1+1
ADC PX2+1
STA RZ+1
SEC ; SUB
LDA RZ
SBC PX3
STA RZ
LDA RZ+1
SBC PX3+1
CLC ; ADD ZTRANS
ADC ZTRANS
LSR
* LSR
STA RZ+1
*
LDA ZPOS ; RY = X * S(X)S(Y) + Y * C(X) - Z * S(X)C(Y)
STA MATOR
LDA SINXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA COSXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA XPOS
STA MATOR
LDA SINXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
CLC ; ADD
LDA PX3
ADC PX2
STA RY
LDA PX3+1
ADC PX2+1
STA RY+1
SEC ; SUB
LDA RY
SBC PX1
STA RY
LDA RY+1
SBC PX1+1
STA RY+1 ; SAVE HI-BYTE AS ZPOS
*
* PERFORM SCALING AND TRANSLATION
*
LDA SCALING ; SCX = SCALE * RX
STA MATOR
LDA RX+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STA SCX
STY SCX+1
*
LDA SCX+1 ; QX = SCX * (1 / RZ)
LDY SCX
LDX RZ+1 ; ONLY HI-BYTE
JSR DIVI
STY QX
*
LDA SCALING ; SCY = SCALE * RY
STA MATOR
LDA RY+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STA SCY
STY SCY+1
*
LDA SCY+1 ; QY = SCY / RZ
LDY SCY
LDX RZ+1 ; ONLY HI-BYTE
JSR DIVI
STY QY
*
CLC ; XD = QX + XT
LDA QX
ADC #XTRANS
STA XD
LDA #$00
STA XD+1
LDA QX
BMI CALCYD ; IF QX < 0 THEN DO NOT ADD CARRY!
LDA #$00
ADC #$00 ; ADD CARRY BIT
STA XD+1
CALCYD CLC ; YD = QY + YT
LDA QY
ADC #YTRANS
STA YD ; ONLY 1 BYTE HERE, NO CARRY!
*
* WRITE DATA BACK TO TABLE
*
WRTPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX
INX
INX ; SKIP 3 BYTES
LDA XD ; SAVE XDRAW POSITION
STA TABLE,X
INX
LDA XD+1
STA TABLE,X
INX
LDA YD ; SAVE YDRAW POSITION
STA TABLE,X
*
INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS INITEND ; ALL DONE
JMP GETPNT
INITEND RTS
*
CYC OFF
*
XPOS DS 1
YPOS DS 1
ZPOS DS 1
XD DS 2
YD DS 2
SAX DS 1
CAX DS 1
SAY DS 1
CAY DS 1
PX1 DS 2 ; INTERMEDIATE RESULTS
PX2 DS 2
PX3 DS 2
RX DS 2
RY DS 2
RZ DS 2
SCX DS 2
SCY DS 2
QX DS 1
QY DS 1
SINXSINY DS 1
SINXCOSY DS 1
COSXSINY DS 1
COSXCOSY DS 1
COSXONE DS 1
SINXONE DS 1
COSYONE DS 1
SINYONE DS 1
DIVRES DS 1
*
********************************
* DRAW BOX AROUND HIRES SCREEN *
********************************
*
DRAWBOX LDX #$03
JSR HCOLOR
LDA #$00
TAY
TAX
JSR HPLOT
LDA #23
LDX #01
JSR HLIN
*
LDA #23
LDX #01
LDY #$BF
JSR HLIN
*
LDA #$00
LDX #$00
LDY #$BF
JSR HLIN
*
LDA #$00
TAY
TAX
JSR HLIN
*
LDY #00
LDX #00
LDA #12
JSR HPOSN
*
LDA #23
LDX #01
LDY #12
JSR HLIN
RTS
*
********************************
*SIGNED DIVISION 14 BIT/6 BIT *
********************************
*
CYC
*
DIVI STY DEND ;
STA DEND+1
STX DOR
*
LDX #$00
DECHK LDA DEND+1 ; DIVIDEND NEG?
BPL DORCHK
INX ; INC X-REG FOR NEG SIGN
LDA DEND
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DEND
LDA DEND+1
SBC #$00
EOR #$FF
STA DEND+1
DORCHK LDA DOR ; DIVISOR NEG?
BPL DIVIGO
INX ; INC X-REG FOR NEG SIGN
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DOR
*
DIVIGO LDA DEND+1 ; TOO LARGE OR ZERO?
CMP DOR ; CMP HI-BYTE WITH DOR!
BCC DLOOP ; NO -> NO ERROR!
JMP DIVERR ; YES -> ERROR!
DLOOP ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP2
DSUBTR SBC DOR
INC DEND
DLOOP2 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR2 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP3
DSUBTR2 SBC DOR
INC DEND
DLOOP3 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR3 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP4
DSUBTR3 SBC DOR
INC DEND
DLOOP4 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR4 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP5
DSUBTR4 SBC DOR
INC DEND
DLOOP5 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR5 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DLOOP6
DSUBTR5 SBC DOR
INC DEND
DLOOP6 ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR6 ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DCONT
DSUBTR6 SBC DOR
INC DEND
*
* STORE RESULTS
*
DCONT STA DOR ; MOVE REMAINDER IN DOR
CLC ; NO ERROR -> CLEAR CARRY
CPX #$01 ; NEG SIGN FOR RESULT?
BNE DIVEND ; NO, SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA DOR
LDA DEND
EOR #$FF
ADC #$01
STA DEND
LDA DOR ; DOR = REMAINDER
DIVEND LDY DEND ; DEND = QUOTIENT
BNE DIVRTS
INY
DIVRTS RTS
DIVERR LDY #$00 ; RETURN 0 AS RESULT
RTS
*
CYC OFF
*
DEND DS 2
DOR DS 1
*
********************************
* 8-BIT UNSIGNED MULTIPL *
********************************
*
CYC
*
UMULT LDX #$00 ; INITIALISE MSIGN = 0
UMKCHK LDA MKAND ; MKAND NEG?
BPL UMTCHK
INX ; INC X-REG FOR NEG SIGN
EOR #$FF
TAY
INY
STY MKAND
UMTCHK LDA MATOR ; MATOR NEG?
LDY MKAND ;
STA PSLO ; INDEX INTO SUM TABLE BY A
STA PSHI
EOR #$FF
STA PDLO ; INDEX INTO DIFF TABLE BY -A-1
STA PDHI
LDA (PSLO),Y ; GET (A+Y)^2/4 (LO BYTE)
SEC
SBC (PDLO),Y ; SUBTRACT (-A+Y)^2/4 (LO BYTE)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
STA MATOR
*
* STORE RESULTS
*
LDA MKAND ; MKAND = LO-BYTE
DEX ; NEG SIGN FOR RESULT?
BNE UMEND ; NO SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA MKAND
LDA MATOR
EOR #$FF
ADC #$00
STA MATOR
TAY
LDA MKAND ; MKAND = LO-BYTE
RTS
UMEND LDY MATOR ; MATOR = HI-BYTE
RTS
*
CYC OFF
*
*
********************************
* 8-BIT SIGNED MULTIPLY *
********************************
*
CYC
*
MULT LDX #$00 ; INITIALISE MSIGN = 0
MKCHK LDA MKAND ; MKAND NEG?
BPL MTCHK
INX
EOR #$FF ; INC X-REG FOR NEG SIGN
TAY ; TWO'S COMPLEMENT
INY
STY MKAND
MTCHK LDA MATOR ; MATOR NEG?
BPL MULTGO
INX
EOR #$FF
TAY ; INC X-REG FOR NEG SIGN
INY
STY MATOR
MULTGO LDA MATOR
LDY MKAND ;
STA PSLO ; INDEX INTO SUM TABLE BY A
STA PSHI
EOR #$FF
STA PDLO ; INDEX INTO DIFF TABLE BY -A-1
STA PDHI
LDA (PSLO),Y ; GET (A+Y)^2/4 (LO BYTE)
SEC
SBC (PDLO),Y ; SUBTRACT (-A+Y)^2/4 (LO BYTE)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; SUBTRACT (-A+Y)^2/4 (HI-BYTE)
STA MATOR
*
* STORE RESULTS
*
LDA MKAND ; MKAND = LO-BYTE
DEX ; NEG SIGN FOR RESULT?
BNE MEND ; NO SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA MKAND
LDA MATOR
EOR #$FF
ADC #$00
STA MATOR
TAY
LDA MKAND ; MKAND = LO-BYTE
RTS
MEND LDY MATOR ; MATOR = HI-BYTE
RTS
*
CYC OFF
*
MKAND DS 1
MATOR DS 1
MSIGN DS 1
*
********************************
* TOP & BOTTOM TEXT MESSAGE *
********************************
*
* PRINT OUT WELCOME TEXT AS SHAPES ON SCREEN
*
WLCMTXT LDX #$03
JSR HCOLOR
STX $F9 ; SET ROT = 0
LDA #$01
STA SCALE ; SET SCALE = 1
LDX #$00
TXTLOOP LDA TXTDAT,X
BEQ TLP2 ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #26 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX XREGDUMP
INX
BNE TXTLOOP
*
TLP2 LDX #$00
TXTLOOP2 LDA TXTDAT2,X
BEQ SUDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
LDX XREGDUMP
INX
BNE TXTLOOP2
SUDONE RTS
*
* TEXT MESSAGES WHEN LOADING 3D-OBJECTS
*
TXTOB1 LDA #TXTDAT3
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB2 LDA #TXTDAT4
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB3 LDA #TXTDAT5
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB4 LDA #TXTDAT6
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB5 LDA #TXTDAT7
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
PRTTXT LDY #$00
LDX #$03
JSR HCOLOR ; SET HCOLOR = 3
TXTLOOP3 LDA (TXTPTR),Y
BEQ TXTDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STY YREGDUMP ; SAVE X-REG COUNTER STATUS
TYA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAY ; MOVE X-POS TO Y-REG
TAX ; ALSO TO X-REG
STY SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDY YREGDUMP
INY
BNE TXTLOOP3
TXTDONE RTS
*
TXTDAT HEX 292231313A01151135
HEX 2901232A33352925223A
HEX 012231312D26013E3C
HEX 00
*
TXTDAT2 HEX 450114250E25262E3001
HEX 0E012E0F28302D30
HEX 2E2326242C01131112
HEX 18014500
*
TXTDAT3 HEX 2D3022252A2F28013529
HEX 2601352635332226252633
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT4 HEX 2D3022252A2F28013529
HEX 2601362E2333262D2D22
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT5 HEX 2D3022252A2F28013529
HEX 2601342A2E312D260124362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT6 HEX 2D3022252A2F28013529
HEX 2601352635332224362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT7 HEX 2D3022252A2F28013529
HEX 2601243623260135382A2F34
HEX 0F0F0F010101010101
HEX 010100
*
LCNT DS 1
XREGDUMP DS 1
YREGDUMP DS 1
SHPDUMP DS 1
SHXPOS DS 1
*
* DELETE BOTTOM TEXT
*
DLTTXT LDX #$00
JSR HCOLOR ; HCOLOR = 0
LDA ASCR
DLTSTRT LDA #180
STA YDELROW ; Y OF LINE TO DELETE
DLTLOOP LDA #32
STA $E6 ; DELETE ON SCREEN 1
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
LDA #64
STA $E6 ; DELETE ON SCREEN 2
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
INC YDELROW
LDA YDELROW
CMP #189 ; LINE 189 REACHED?
BCC DLTLOOP ; NO -> DELETE NEXT LINE
DLTEND RTS ; END OF LOOP
*
YDELROW DS 1
*
********************************
* LOAD 3D-OBJECTS IN MEMORY *
********************************
*
LOAD1 JSR TXTOB1 ; PRINT LOADING MESSAGE
LOAD01 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT1.3D,A$7200"
HEX 8D00
RTS
*
LOAD2 JSR TXTOB2
LOAD02 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT2.3D,A$7200"
HEX 8D00
RTS
*
LOAD3 JSR TXTOB3
LOAD03 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT3.3D,A$7200"
HEX 8D00
RTS
*
LOAD4 JSR TXTOB4
LOAD04 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT4.3D,A$7200"
HEX 8D00
RTS
*
LOAD5 JSR TXTOB5
LOAD05 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT5.3D,A$7200"
HEX 8D00
RTS
*
PRINT PLA
STA PTR
PLA
STA PTR+1
LDY #$01
P0 LDA (PTR),Y
BEQ PFIN
JSR COUT
INY
BNE P0
CHK
*
PFIN CLC
TYA
ADC PTR
STA PTR
LDA PTR+1
ADC #$00
PHA
LDA PTR
PHA
PEXIT RTS
*
********************************
* UNDRAW LINES *
********************************
*
UDRWLNS LDA #$00
*
LDY $E6
CPY #$20
BEQ UDRWSCR1
JMP UDRWSCR2
UDRWSCR1 LDX #$0B
UDRWLP1 STA $2200,X
STA $2600,X
STA $2A00,X
STA $2E00,X
STA $3200,X
STA $3600,X
STA $3A00,X
STA $3E00,X
STA $2280,X
STA $2680,X
STA $2A80,X
STA $2E80,X
STA $3280,X
STA $3680,X
STA $3A80,X
STA $3E80,X
STA $2300,X
STA $2700,X
STA $2B00,X
STA $2F00,X
STA $3300,X
STA $3700,X
STA $3B00,X
STA $3F00,X
STA $2380,X
STA $2780,X
STA $2B80,X
STA $2F80,X
STA $3380,X
STA $3780,X
STA $3B80,X
STA $3F80,X
STA $2028,X
STA $2428,X
STA $2828,X
STA $2C28,X
STA $3028,X
STA $3428,X
STA $3828,X
STA $3C28,X
STA $20A8,X
STA $24A8,X
STA $28A8,X
STA $2CA8,X
STA $30A8,X
STA $34A8,X
STA $38A8,X
STA $3CA8,X
STA $2128,X
STA $2528,X
STA $2928,X
STA $2D28,X
STA $3128,X
STA $3528,X
STA $3928,X
STA $3D28,X
STA $21A8,X
STA $25A8,X
STA $29A8,X
STA $2DA8,X
STA $31A8,X
STA $35A8,X
STA $39A8,X
STA $3DA8,X
STA $2228,X
STA $2628,X
STA $2A28,X
STA $2E28,X
STA $3228,X
STA $3628,X
STA $3A28,X
STA $3E28,X
STA $22A8,X
STA $26A8,X
STA $2AA8,X
STA $2EA8,X
STA $32A8,X
STA $36A8,X
STA $3AA8,X
STA $3EA8,X
STA $2328,X
STA $2728,X
STA $2B28,X
STA $2F28,X
STA $3328,X
STA $3728,X
STA $3B28,X
STA $3F28,X
STA $23A8,X
STA $27A8,X
STA $2BA8,X
STA $2FA8,X
STA $33A8,X
STA $37A8,X
STA $3BA8,X
STA $3FA8,X
*
STA $2050,X
STA $2450,X
STA $2850,X
STA $2C50,X
STA $3050,X
STA $3450,X
STA $3850,X
STA $3C50,X
STA $20D0,X
STA $24D0,X
STA $28D0,X
STA $2CD0,X
STA $30D0,X
STA $34D0,X
STA $38D0,X
STA $3CD0,X
STA $2150,X
STA $2550,X
STA $2950,X
STA $2D50,X
STA $3150,X
STA $3550,X
STA $3950,X
STA $3D50,X
STA $21D0,X
STA $25D0,X
STA $29D0,X
STA $2DD0,X
STA $31D0,X
STA $35D0,X
STA $39D0,X
STA $3DD0,X
INX
CPX #29
BEQ UDRW1RTS
JMP UDRWLP1
UDRW1RTS RTS
UDRWSCR2 LDX #$0B
UDRWLP2 STA $4200,X
STA $4600,X
STA $4A00,X
STA $4E00,X
STA $5200,X
STA $5600,X
STA $5A00,X
STA $5E00,X
STA $4280,X
STA $4680,X
STA $4A80,X
STA $4E80,X
STA $5280,X
STA $5680,X
STA $5A80,X
STA $5E80,X
STA $4300,X
STA $4700,X
STA $4B00,X
STA $4F00,X
STA $5300,X
STA $5700,X
STA $5B00,X
STA $5F00,X
STA $4380,X
STA $4780,X
STA $4B80,X
STA $4F80,X
STA $5380,X
STA $5780,X
STA $5B80,X
STA $5F80,X
STA $4028,X
STA $4428,X
STA $4828,X
STA $4C28,X
STA $5028,X
STA $5428,X
STA $5828,X
STA $5C28,X
STA $40A8,X
STA $44A8,X
STA $48A8,X
STA $4CA8,X
STA $50A8,X
STA $54A8,X
STA $58A8,X
STA $5CA8,X
*
STA $4128,X
STA $4528,X
STA $4928,X
STA $4D28,X
STA $5128,X
STA $5528,X
STA $5928,X
STA $5D28,X
STA $41A8,X
STA $45A8,X
STA $49A8,X
STA $4DA8,X
STA $51A8,X
STA $55A8,X
STA $59A8,X
STA $5DA8,X
STA $4228,X
STA $4628,X
STA $4A28,X
STA $4E28,X
STA $5228,X
STA $5628,X
STA $5A28,X
STA $5E28,X
STA $42A8,X
STA $46A8,X
STA $4AA8,X
STA $4EA8,X
STA $52A8,X
STA $56A8,X
STA $5AA8,X
STA $5EA8,X
STA $4328,X
STA $4728,X
STA $4B28,X
STA $4F28,X
STA $5328,X
STA $5728,X
STA $5B28,X
STA $5F28,X
STA $43A8,X
STA $47A8,X
STA $4BA8,X
STA $4FA8,X
STA $53A8,X
STA $57A8,X
STA $5BA8,X
STA $5FA8,X
*
STA $4050,X
STA $4450,X
STA $4850,X
STA $4C50,X
STA $5050,X
STA $5450,X
STA $5850,X
STA $5C50,X
STA $40D0,X
STA $44D0,X
STA $48D0,X
STA $4CD0,X
STA $50D0,X
STA $54D0,X
STA $58D0,X
STA $5CD0,X
STA $4150,X
STA $4550,X
STA $4950,X
STA $4D50,X
STA $5150,X
STA $5550,X
STA $5950,X
STA $5D50,X
STA $41D0,X
STA $45D0,X
STA $49D0,X
STA $4DD0,X
STA $51D0,X
STA $55D0,X
STA $59D0,X
STA $5DD0,X
INX
CPX #29
BEQ UDRW2RTS
JMP UDRWLP2
UDRW2RTS RTS
*
LST OFF
*
CHK
*
PLOT3D8.S - 3D-Demo Version 1.2
********************************
* 3D-DEMO *
* *
* BY MARC GOLOMBECK *
* *
* VERSION 1.2 / 10.04.2017 *
* *
* NEEDS THE FOLLOWING DATA *
* ALREADY LOADED INTO MEMORY: *
* *
* $7000: SINE/COSINE-TABLE *
* $7200: POINT AND LINE DATA *
* $7400: SHAPE TABLE *
* $7A00: MULTIPLICATION TABLE *
* *
* CONTROLLED VIA JOYSTICK AND *
* KEYBOARD: *
* *
* PDL(0/1/2): ROTATION+ZOOM *
* PBN(0/1/2): RESET/STOP/EXIT *
* KEYS 1-5 : CHOOSE 3D-OBJECT *
* KEYS +/- : ALTERNATE ZOOM *
* KEY B : TOGGLE BENCHMARK *
* *
********************************
*
ORG $6000
*
HGR2 EQU $F3D8 ; SWITCH TO HIRES2
HGR EQU $F3E2 ; SWITCH TO HIRES1
HCLR EQU $F3F2 ; CLEAR HIRES SCREEN TO BLACK1
HCOLOR EQU $F6F0 ; SET HCOLOR
HPOSN EQU $F411 ; SET HIRES-CURSOR NO DRAW
HPLOT EQU $F457 ; DRAW HIRES-PIXEL
HLIN EQU $F53A ; DRAW HIRES-LINE
PREAD EQU $FB1E ; READ PADDLES
WAIT EQU $FCA8 ; WAIT-ROUTINE
PB0 EQU $C061 ; PUSH-BUTTON 0
PB1 EQU $C062 ; PUSH-BUTTON 1
PB2 EQU $C063 ; PUSH-BUTTON 2
HOME EQU $FC58 ; CLEAR SCREEN
COUT EQU $FDED ; PRINT CHARACTER
KYBD EQU $C000 ; READ KEYBOARD
STROBE EQU $C010 ; CLEAR KEYBOARD
SHNUM EQU $F730 ; GET ADRESS OF SHAPE NUMBER
SHDRAW EQU $F605 ; DRAW SHAPE ON SCREEN
BELL EQU $FBDD ; RING BELL
*
SINTAB EQU $7000 ; BASE ADRESS OF SINE TABLE
COSTAB EQU $7040 ; BASE ADRESS OF COSINE TABLE
NUMPNT EQU $7200 ; NUMBER OF POINTS TO DRAW
TABLE EQU $7201 ; BASE ADRESS FOR POINT TABLE
SHTAB EQU $7400 ; BASE ADRESS OF SHAPES-68
SHTABPTR EQU $E8 ; POINTER TO SHAPE-TABLE
SSQLO EQU $7A00 ; MULT TAB
SSQHI EQU $7C00 ; MULT TAB
DSQLO EQU $7E00 ; MULT TAB
DSQHI EQU $8000 ; MULT TAB
*
XTRANS EQU $8B ; TRANSLATION TO SCREEN CENTER
YTRANS EQU $5F
ZTRANS EQU $FE ; MOVE 3D OBJECT AWAY FROM CAMERA
*
RADIUS EQU $30F ; CIRCLE RADIUS
TXTPTR EQU $06 ; POINTER FOR TEXT OUTPUT
PTR EQU $08 ; POINTER FOR DOS COMMAND
LOOPCNTY EQU $FA ; Y-ROT-COUNTER
ROTSPDY EQU $FB ; Y-ROTATIONAL SPEED
LOOPCNTX EQU $FC ; X-ROT-COUNTER
ROTSPDX EQU $FD ; X-ROTATIONAL SPEED
PNTCNT EQU $09 ; WHICH POINT TO DRAW?
JOYCNT EQU $30C ; COUNTER FOR JOYSTICK REQUEST
SCALING EQU $FF ; SCALING
XDRAW EQU $300 ; X-POSITION FOR DRAW
YDRAW EQU $302 ; Y-POSITION FOR DRAW
XDRAWO EQU $304 ; OLD POSITION X
YDRAWO EQU $306 ; OLD POSITION Y
XDRAW2 EQU $308 ; UNDRAW CURSOR X
YDRAW2 EQU $30A ; UNDRAW CURSOR Y
ASCR EQU $30B ; ACTIVE SCREEN TO DRAW
BENCHM EQU $30D ; BENCHMARK ON?
*
PSLO EQU $D8 ; USING FAC-ADRESS RANGE
PSHI EQU $DA
PDLO EQU $DC ; USING ARG-ADRESS RANGE
PDHI EQU $DE
*
ENTRY JSR SETUP ; SETUP GRAPHIC
*
TABLESET JSR WLCMTXT ; SHOW WELCOME MESSAGE
*
INILOOP LDA #$00 ; INIT LOOP
STA LOOPCNTY ; CURRENT Y-STEP
LDA #$10
STA LOOPCNTX ; CURRENT X-STEP
*
* READ PADDELS
*
LOOP INC JOYCNT ; MAIN LOOP STARTS HERE
LDA JOYCNT
CMP #$02
BCC READ1 ; LESS THAN 3 CYCLES
LDA #$00 ; READ PADDLE EVERY 3 CYCLES
STA JOYCNT
*
PREAD0 LDX #$00 ; VARY Y-ROT SPEED
JSR PREAD ; PADDLE (0)
CPY #$64
BCC INCSPDY ; DECREASE SPEED
CPY #$9B
BCS DECSPDY ; INCREASE SPEED
BCC PREAD1 ; 256-STEP CIRCLE LOOP
*
DECSPDY LDA ROTSPDY ; DECREASE ANGLE
CMP #$01
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ROTSPDY
JMP PREAD1 ; JUMP TO NEXT COMMAND
INCSPDY LDA ROTSPDY ; DECREASE WAIT COUNTER
CMP #$20
BCS PREAD1 ; MAXIMUM 10
INC ROTSPDY
*
PREAD1 LDX #$01 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
BCC DECSPDX ; DECREASE SPEED
CPY #$9B
BCS INCSPDX ; INCREASE SPEED
BCC PREAD2 ; 256-STEP CIRCLE LOOP
*
DECSPDX LDA ROTSPDX ; DECREASE ANGLE
CMP #$01
BCC PREAD2 ; LOOPCNT STILL POSITIVE
DEC ROTSPDX
JMP PREAD2 ; JUMP TO NEXT COMMAND
INCSPDX LDA ROTSPDX ; DECREASE WAIT COUNTER
CMP #$20
BCS PREAD2 ; MAXIMUM 10
INC ROTSPDX
*
*
PREAD2 LDX #$02 ; VARY X-ROT SPEED
JSR PREAD ; PADDLE (1)
CPY #$64
BCC DECZTRS ; DECREASE SPEED
CPY #$9B
BCS INCZTRS ; INCREASE SPEED
BCC READ1 ; 256-STEP CIRCLE LOOP
*
INCZTRS LDA ZTRANS ; DECREASE DISTANCE
CMP #$43
BCC READ1 ; LOOPCNT STILL POSITIVE
DEC ZTRANS
JMP READ1 ; JUMP TO NEXT COMMAND
DECZTRS LDA ZTRANS ; INCREASE DISTANCE
CMP #$7F
BCS READ1 ; MAIXMUM 127
INC ZTRANS
*
READ1 CLC ; CALC NEXT STEP
LDX #$00
LDA LOOPCNTY
BPL READ02
INX ; INIT FOR BENCHMARK
READ02 ADC ROTSPDY ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU -10
STA LOOPCNTY
LDA LOOPCNTY
BPL READ01 ;
INX
READ01 CPX #01
BNE READ03 ; BENCHMARK LOOP START
LDY BENCHM
BEQ READ03 ; BENCHMARK OFF
JSR BELL ; REING BELL
READ03 CLC
LDA LOOPCNTX
ADC ROTSPDX ; ADD NEXT STEP
ADC #$F6 ; ACCU = ACCU - 10
STA LOOPCNTX
*
JSR INITPNTS ; CALC NEW POINT POSITIONS
JSR UDRWLNS ; UNDRAW LINES
*
* READ KEYBOARD FOR LOADING NEW OBJECTS
*
LDA KYBD
CMP #$80
BCC NOKEY ; NO KEY IS PRESSED
KEY1 CMP #$B1 ; KEY '1' IS PRESSED
BNE KEY2
JSR LOAD1 ; LOAD OBJECT 1
JMP ENDKEY ; DONE
KEY2 CMP #$B2 ; KEY '2' IS PRESSED
BNE KEY3
JSR LOAD2
JMP ENDKEY ; DONE
KEY3 CMP #$B3 ; KEY '3' IS PRESSED
BNE KEY4
JSR LOAD3
JMP ENDKEY
KEY4 CMP #$B4 ; KEY '4' IS PRESSED
BNE KEY5
JSR LOAD4
JMP ENDKEY
KEY5 CMP #$B5 ; KEY '5' IS PRESSED
BNE KEYPLUS ; NO VALID KEY IS PRESSED
JSR LOAD5
JMP ENDKEY
KEYPLUS CMP #$AB ; KEY '+' IS PRESSED
BNE KEYMINUS
LDA STROBE
JMP INCZTRS ; INCREASE ZOOM
KEYMINUS CMP #$AD ; KEY '-' IS PRESSED
BNE KEYB
LDA STROBE
JMP DECZTRS
KEYB CMP #$C2 ; KEY 'B' IS PRESSED
BNE NOKEY
LDA BENCHM ; TOGGLE BENCHMARK ON/OFF
BEQ BENCHON
DEC BENCHM ; TOGGLE OFF
BEQ ENDKEY1
BENCHON INC BENCHM ; TOGGLE ON
BNE ENDKEY1
ENDKEY JSR SETUP
JSR WLCMTXT ; WRITE WELCOME MESSAGE ON SCREEN
JSR INITPNTS
ENDKEY1 LDA STROBE
*
NOKEY JSR DRWLNS ; DRAW LINES
*
* CHECK PUSHBUTTONS
*
LDA PB1 ; PUSHBUTTON 1 PRESSED?
BMI END ; EXIT PROGRAM!
LDA PB2 ; PUSHBUTTON 2 PRESSED?
BPL PB0CHK ; NO -> CHECK PB0
LDA #$0A ; STOP ROTATION IMMEDIATELY
STA ROTSPDY ; RESET Y-ROT SPEED = 0
STA ROTSPDX ; RESET X-ROT SPEED = 0
PB0CHK LDA PB0 ; PUSHBUTTON 0 PRESSED?
BPL GOLOOP ; NO -> DO NEXT LOOP
LDA #$00 ; RESET ASPECT
STA LOOPCNTX ; BACK TO INIT POS
STA LOOPCNTY
*
GOLOOP JMP LOOP ; START AGAIN
*
END LDA #$00
STA $C051 ; SWITCH TO TEXT
STA $C052
STA $C054
JSR HOME ; CLEAR SCREEN
JMP $03D0 ; DOS WARM START NO RTS HERE!
*
* SETUP GRAPHICS & DATA
*
SETUP LDA #$00
STA $C050 ; SWITCH ON GRAPHICS
STA $C057 ; SWITCH TO HIRES
STA BENCHM ; BENCHMARK OFF
LDA #32
STA $E6 ; DRAW ON 1
STA $C055 ; SHOW 2
JSR HCLR ; CLEAR HGR
JSR DRAWBOX ; DRAW BOX ON HIRES 1
LDA #64
STA $E6 ; DRAW ON 2
STA $C054
JSR HCLR ; CLEAR HGR2
JSR DRAWBOX ; DRAW BOX ON HIRES 2
LDA #$03 ; INIT HCOLOR = 3
JSR HCOLOR
LDA #$0A ; INITIAL RADIUS
STA RADIUS
STA ROTSPDX ; INITIAL X-ROT SPEED = 0
LDA #$0F
STA ROTSPDY ; INITIAL Y-ROT SPEED = 1
LDA #$01
STA ASCR ; DRAW ON HIRES 1
STA JOYCNT ; SET JOYSTICK REQUEST COUNTER
LDA #$90 ; SCALING
STA SCALING
LDA #$50
STA ZTRANS ; MOVE OBJECT AWAY FROM CAMERA
LDA #SHTAB
STA SHTABPTR+1
LDA #SSQLO/256 ; SETUP MULT-TAB
STA PSLO+1
LDA #SSQHI/256
STA PSHI+1
LDA #DSQLO/256
STA PDLO+1
LDA #DSQHI/256
STA PDHI+1
RTS
*
********************************
* UNDRAW LINES *
********************************
*
UDRWLNS LDA #$00
*
STA PNTCNT
LDX #$00 ; DELETE OLD LINES
JSR HCOLOR
UGETPNT2 LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
LDA $E6 ; WHICH SCREEN?
CMP #$20 ; SCREEN 1?
BEQ UDRW2 ; YES -> SKIP 6 BYTES
INX ; SKIP 9 BYTES -> SCREEN 2
INX
INX
UDRW2 INX
INX
INX
INX
INX
INX
LDA TABLE,X ; GET OLD XPOS LO-BYTE
STA XDRAW
INX
LDA TABLE,X ; GET OLD XPOS HI-BYTE
STA XDRAW+1
INX
LDA TABLE,X ; GET OLD YPOS
STA YDRAW
INX
LDA $E6 ; WHICH SCREEN?
CMP #$40 ; SCREEN 2?
BEQ EVLPNTS2 ; YES -> EVAL POINTS NOW
INX ; NO -> SKIP 3 BYTES
INX
INX
*
* EVALUATE POINTS TO DRAW TO
*
EVLPNTS2 LDA #$04
STA MAXDRAW ; NUMBER OF LINES TO DRAW
UDRWNXT LDA TABLE,X
BEQ UNXTPNT ; NOTHING MORE TO DRAW
TAY ; SUBTRACT 1 TO GET CORREC
DEY ; POINT NUMBER
TYA
ASL ; CALC BASE ADRESS OF POINT TO
ASL ; DRAW TO
ASL
ASL
TAY ; Y = POINNUMBER * 16
LDA $E6 ; WHICH SCREEN?
CMP #$20 ; SCREEN 1?
BEQ UDRW1 ; YES -> SKIP 6 BYTES
INY ; SKIP 9 BYTES FOR SCREEN 2
INY
INY
UDRW1 INY
INY
INY
INY
INY
INY
LDA TABLE,Y ; READ OUT POINTS TO DRAW TO
STA XTO
INY
LDA TABLE,Y
STA XTO+1
INY
LDA TABLE,Y
STA YTO
*
STX XREGSAVE ; SAVE X-REG ON STACK
LDX XDRAW
LDY XDRAW+1
LDA YDRAW
JSR HPOSN ; POSITION CURSOR
LDA XTO
LDX XTO+1
LDY YTO
JSR HLIN ; DRAW LINE
LDX XREGSAVE ; RESTORE X-REG
DEC MAXDRAW ; MAXIMUM NUMBER OF LINES
BEQ UNXTPNT ; REACHED? IF YES NEXT POINT
INX ; INC X-REG TO NEXT POINT
BNE UDRWNXT ; DRAW NEXT LINE
*
UNXTPNT INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS UDRWEND ; ALL DONE
JMP UGETPNT2
UDRWEND RTS
*
********************************
* DRAW LINES *
********************************
*
DRWLNS LDA #$00
STA PNTCNT
LDA ASCR
CMP #$01
BEQ DRWSCR1
BNE SETCLR
DRWSCR1 LDA #32
SETCLR LDX #$03 ; HCOLOR = 3
JSR HCOLOR
GETPNT2 LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX ; SKIP 3 BYTES
INX
INX
LDA TABLE,X ; GET XPOS LO-BYTE
STA XDRAW
INX
LDA TABLE,X ; GET XPOS HI-BYTE
STA XDRAW+1
INX
LDA TABLE,X ; GET YPOS
STA YDRAW
INX
LDA $E6 ; WHICH SCREEN?
CMP #$20 ; SCREEN 1?
BEQ SVOLD ; YES -> WRITE TO OLDPOS1
INX ; NO -> SKIP 3 BYTES
INX ; WRITE TO OLDPOS2
INX
SVOLD LDA XDRAW ; SAVE AS OLD-POS
STA TABLE,X
INX
LDA XDRAW+1
STA TABLE,X
INX
LDA YDRAW
STA TABLE,X
INX
LDA $E6 ; WHICH SCREEN?
CMP #$40 ; SCREEN 2?
BEQ EVLPNTS ; YES -> EVAL POINTS NOW
INX ; NO -> SKIP 3 BYTES
INX
INX
*
* EVALUATE POINTS TO DRAW TO
*
EVLPNTS LDA #$04
STA MAXDRAW ; NUMBER OF LINES TO DRAW
DRWNXT LDA TABLE,X
BEQ NXTPNT ; NOTHING MORE TO DRAW
TAY ; SUBTRACT 1 TO GET CORREC
DEY ; POINT NUMBER
TYA
ASL ; CALC BASE ADRESS OF POINT TO
ASL ; DRAW TO
ASL
ASL
TAY ; Y = POINNUMBER * 16
INY ; SKIP 3 BYTES
INY
INY
LDA TABLE,Y ; READ OUT POINTS TO DRAW TO
STA XTO
INY
LDA TABLE,Y
STA XTO+1
INY
LDA TABLE,Y
STA YTO
*
STX XREGSAVE ; SAVE X-REG ON STACK
LDX XDRAW
LDY XDRAW+1
LDA YDRAW
JSR HPOSN ; POSITION CURSOR
LDA XTO
LDX XTO+1
LDY YTO
JSR HLIN ; DRAW LINE
LDX XREGSAVE ; RESTORE X-REG
DEC MAXDRAW ; MAXIMUM NUMBER OF LINES
BEQ NXTPNT ; REACHED? IF YES NEXT POINT
INX ; INC X-REG TO NEXT POINT
BNE DRWNXT ; DRAW NEXT LINE
*
NXTPNT INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS DRWEND ; ALL DONE
JMP GETPNT2
DRWEND LDA ASCR ; DISPLAY DRAW-SCREEN
CMP #$02
BEQ DISP2 ; SHOW SCREEN 2
LDA #64
STA $E6 ; DRAW ON 2
STA $C054 ; SWITCH TO SCREEN1
INC ASCR ; ASCR = 2
BNE DRWEND2
DISP2 STA $C055 ; SWITCH TO SCREEN2
LDA #32
STA $E6 ; DRAW ON 1
DEC ASCR ; ASCR = 1
DRWEND2 RTS
*
XTO DS 2 ; DRAW TO X-POS
YTO DS 1 ; DRAW TO Y-POS
MAXDRAW DS 1 ; MAXIMUM LINES TO DRAW
XREGSAVE DS 1 ; TEMPORARY SAVE FOR X-REG
*
*
********************************
* INIT POINT POSITIONS *
********************************
*
CYC ; PRINT CYCLES
*
INITPNTS LDA #$00
STA PNTCNT
GETPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
LDA TABLE,X ; GET XPOS
STA XPOS
INX
LDA TABLE,X ; GET YPOS
STA YPOS
INX
LDA TABLE,X ; GET ZPOS
STA ZPOS
*
* EVAL SIN/COS-TAB
*
LDX LOOPCNTX ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR X
STA SAX
LDA COSTAB,X ; GET COSINUS FOR X
STA CAX
LDX LOOPCNTY ; INITIAL POS
LDA SINTAB,X ; GET SINUS FOR Y
STA SAY
LDA COSTAB,X ; GET COSINUS FOR Y
STA CAY
LDA SAX ; SINXSINY = SINX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR MULT
STY SINXSINY ; ONLY HI-BYTE
LDA SAX ; SINXCOSY = SINX * COSY
STA MATOR
LDA CAY
STA MKAND
JSR MULT
STY SINXCOSY ; ONLY HI-BYTE
LDA CAX ; COSXSINY = COSX * SINY
STA MATOR
LDA SAY
STA MKAND
JSR MULT
STY COSXSINY
LDA CAX ; COSXCOSY = COSX * COSY
STA MATOR
LDA CAY
STA MKAND
JSR MULT
STY COSXCOSY
LDA CAX ; COSXONE = COSX * $7F (= 1)
BPL CX1
TAY
DEY
TYA
EOR #$FF ; TWO'S COMPLEMENT
LSR
EOR #$FF
TAY
INY
STY COSXONE
BEQ SX1
BNE SX1
CX1 LSR ; SHORT METHOD IMPLEMENTED HERE
STA COSXONE ; DOES NOT NEED THE SMULT!
SX1 LDA SAX ; SINXONE = SINX * $7F (= 1)
BPL SX10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINXONE
BEQ CY1
BNE CY1
SX10 LSR
STA SINXONE
CY1 LDA CAY ; COSYONE = COSX * $7F (= 1)
BPL CY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY COSYONE
BEQ SY1
BNE SY1
CY10 LSR
STA COSYONE
SY1 LDA SAY ; SINYONE = SINX * $7F (= 1)
BPL SY10
TAY
DEY
TYA
EOR #$FF
LSR
EOR #$FF
TAY
INY
STY SINYONE
BEQ STRTROT
BNE STRTROT
SY10 LSR
STA SINYONE
*
* ROTATE AROUND X AND Y
*
STRTROT LDA XPOS ; RX = X * COS(Y) + Z * SIN(Y)
STA MATOR
LDA COSYONE
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA ZPOS
STA MATOR
LDA SINYONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
CLC ; ADD
LDA PX1
ADC PX2
STA RX
LDA PX1+1
ADC PX2+1
STA RX+1 ; SAVE HI-BYTE AS XPOS
*
LDA ZPOS ; RZ = Z * C(X)C(Y) + Y * S(X) - X * C(X)S(Y)
STA MATOR
LDA COSXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA SINXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA XPOS
STA MATOR
LDA COSXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
CLC ; ADD
LDA PX1
ADC PX2
STA RZ
LDA PX1+1
ADC PX2+1
STA RZ+1
SEC ; SUB
LDA RZ
SBC PX3
STA RZ
LDA RZ+1
SBC PX3+1
CLC ; ADD ZTRANS
ADC ZTRANS
LSR
STA RZ+1
*
LDA ZPOS ; RY = X * S(X)S(Y) + Y * C(X) - Z * S(X)C(Y)
STA MATOR
LDA SINXCOSY
STA MKAND
JSR MULT
STA PX1
STY PX1+1
LDA YPOS
STA MATOR
LDA COSXONE
STA MKAND
JSR MULT
STA PX2
STY PX2+1
LDA XPOS
STA MATOR
LDA SINXSINY
STA MKAND
JSR MULT
STA PX3
STY PX3+1
CLC ; ADD
LDA PX3
ADC PX2
STA RY
LDA PX3+1
ADC PX2+1
STA RY+1
SEC ; SUB
LDA RY
SBC PX1
STA RY
LDA RY+1
SBC PX1+1
STA RY+1 ; SAVE HI-BYTE AS ZPOS
*
* PERFORM SCALING AND TRANSLATION
*
LDA SCALING ; SCX = SCALE * RX
STA MATOR
LDA RX+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STA SCX
STY SCX+1
*
LDA SCX+1 ; QX = SCX / RZ
LDY SCX
LDX RZ+1 ; ONLY HI-BYTE
JSR DIVI
STY QX
*
LDA SCALING ; SCY = SCALE * RY
STA MATOR
LDA RY+1 ; ONLY HI-BYTE!
STA MKAND
JSR UMULT
STA SCY
STY SCY+1
*
LDA SCY+1 ; QY = SCY / RZ
LDY SCY
LDX RZ+1 ; ONLY HI-BYTE
JSR DIVI
STY QY
*
CLC ; XD = QX + XT
LDA QX
ADC #XTRANS
STA XD
LDA #$00
STA XD+1
LDA QX
BMI CALCYD ; IF QX < 0 THEN DO NOT ADD CARRY!
LDA #$00
ADC #$00 ; ADD CARRY BIT
STA XD+1
CALCYD CLC ; YD = QY + YT
LDA QY
ADC #YTRANS
STA YD ; ONLY 1 BYTE HERE, NO CARRY!
*
* WRITE DATA BACK TO TABLE
*
WRTPNT LDA PNTCNT
ASL
ASL
ASL
ASL ; X = CNTR*16
TAX
INX
INX
INX ; SKIP 3 BYTES
LDA XD ; SAVE XDRAW POSITION
STA TABLE,X
INX
LDA XD+1
STA TABLE,X
INX
LDA YD ; SAVE YDRAW POSITION
STA TABLE,X
*
INC PNTCNT
LDA PNTCNT
CMP NUMPNT
BCS INITEND ; ALL DONE
JMP GETPNT
INITEND RTS
*
CYC OFF
*
XPOS DS 1
YPOS DS 1
ZPOS DS 1
XD DS 2
YD DS 2
SAX DS 1
CAX DS 1
SAY DS 1
CAY DS 1
PX1 DS 2 ; INTERMEDIATE RESULTS
PY1 DS 2
PZ1 DS 2
PX2 DS 2
PY2 DS 2
PZ2 DS 2
PX3 DS 2
RX DS 2
RY DS 2
RZ DS 2
SCX DS 2
SCY DS 2
QX DS 1
QY DS 1
SINXSINY DS 1
SINXCOSY DS 1
COSXSINY DS 1
COSXCOSY DS 1
COSXONE DS 1
SINXONE DS 1
COSYONE DS 1
SINYONE DS 1
*
********************************
* DRAW BOX AROUND HIRES SCREEN *
********************************
*
DRAWBOX LDX #$03
JSR HCOLOR
LDA #$00
TAY
TAX
JSR HPLOT
LDA #23
LDX #01
JSR HLIN
*
LDA #23
LDX #01
LDY #$BF
JSR HLIN
*
LDA #$00
LDX #$00
LDY #$BF
JSR HLIN
*
LDA #$00
TAY
TAX
JSR HLIN
*
LDY #00
LDX #00
LDA #12
JSR HPOSN
*
LDA #23
LDX #01
LDY #12
JSR HLIN
RTS
*
********************************
*SIGNED DIVISION 16 BIT/8 BIT *
********************************
*
CYC
*
DIVI STY DEND ;
STA DEND+1
STX DOR
*
LDX #$00
DECHK LDA DEND+1 ; DIVIDEND NEG?
BPL DORCHK
INX ; INC X-REG FOR NEG SIGN
LDA DEND
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DEND
LDA DEND+1
SBC #$00
EOR #$FF
STA DEND+1
DORCHK LDA DOR ; DIVISOR NEG?
BPL DIVIGO
INX ; INC X-REG FOR NEG SIGN
SEC ; TWO'S COMPLEMENT
SBC #$01
EOR #$FF
STA DOR
*
DIVIGO LDA DEND+1 ; TOO LARGE OR ZERO?
CMP DOR ; CMP HI-BYTE WITH DOR!
BCS DIVERR ; YES -> ERROR!
LDY #$06 ; 6 LOOPS -> 6-BIT ACCURACY
DLOOP ASL DEND ; DOUBLE SHIFT DIVIDEND
ROL ; DEND+1 STILL IN ACCU!
BCS DSUBTR ; SUBTRACTION WHEN CARRY IS SET
CMP DOR
BCC DCONT
DSUBTR SBC DOR
INC DEND
DCONT DEY
BNE DLOOP
*
* STORE RESULTS
*
STA DOR ; MOVE REMAINDER IN DOR
CLC ; NO ERROR -> CLEAR CARRY
CPX #$01 ; NEG SIGN FOR RESULT?
BNE DIVEND ; NO, SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA DOR
LDA DEND
EOR #$FF
ADC #$01
STA DEND
LDA DOR ; DOR = REMAINDER
DIVEND LDY DEND ; DEND = QUOTIENT
BNE DIVRTS
INY
DIVRTS RTS
DIVERR LDY #$00 ; RETURN 0 AS RESULT
RTS
*
CYC OFF
*
DEND DS 2
DOR DS 1
*
********************************
* 8-BIT UNSIGNED MULTIPL *
********************************
*
CYC
*
UMULT LDX #$00 ; INITIALISE MSIGN = 0
UMKCHK LDA MKAND ; MKAND NEG?
BPL UMTCHK
INX ; INC X-REG FOR NEG SIGN
EOR #$FF
TAY
INY
STY MKAND
UMTCHK LDA MATOR ; MATOR NEG?
LDY MKAND ;
STA PSLO ; Index into sum table by A
STA PSHI
EOR #$FF
STA PDLO ; Index into diff table by -A-1
STA PDHI
LDA (PSLO),Y ; Get (a+y)^2/4 (lo byte)
SEC
SBC (PDLO),Y ; Subtract (-a+y)^2/4 (lo byte)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; Subtract (-A+Y)^2/4 (HI-BYTE)
STA MATOR
*
* STORE RESULTS
*
LDA MKAND ; MKAND = LO-BYTE
DEX ; NEG SIGN FOR RESULT?
BNE UMEND ; NO SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA MKAND
LDA MATOR
EOR #$FF
ADC #$00
STA MATOR
TAY
LDA MKAND ; MKAND = LO-BYTE
RTS
UMEND LDY MATOR ; MATOR = HI-BYTE
RTS
*
CYC OFF
*
*
********************************
* 8-BIT SIGNED MULTIPLY *
********************************
*
CYC
*
MULT LDX #$00 ; INITIALISE MSIGN = 0
MKCHK LDA MKAND ; MKAND NEG?
BPL MTCHK
INX
EOR #$FF ; INC X-REG FOR NEG SIGN
TAY ; TWO'S COMPLEMENT
INY
STY MKAND
MTCHK LDA MATOR ; MATOR NEG?
BPL MULTGO
INX
EOR #$FF
TAY ; INC X-REG FOR NEG SIGN
INY
STY MATOR
MULTGO LDA MATOR
LDY MKAND ;
STA PSLO ; Index into sum table by A
STA PSHI
EOR #$FF
STA PDLO ; Index into diff table by -A-1
STA PDHI
LDA (PSLO),Y ; Get (a+y)^2/4 (lo byte)
SEC
SBC (PDLO),Y ; Subtract (-a+y)^2/4 (lo byte)
STA MKAND ; SAVE IT
LDA (PSHI),Y ; GET (A+Y)^2/4 (HI-BYTE)
SBC (PDHI),Y ; Subtract (-A+Y)^2/4 (HI-BYTE)
STA MATOR
*
* STORE RESULTS
*
LDA MKAND ; MKAND = LO-BYTE
DEX ; NEG SIGN FOR RESULT?
BNE MEND ; NO SIGN IS POSITIVE -> END
EOR #$FF ; TWO'S COMPLEMENT OF ACCU
CLC
ADC #$01
STA MKAND
LDA MATOR
EOR #$FF
ADC #$00
STA MATOR
TAY
LDA MKAND ; MKAND = LO-BYTE
RTS
MEND LDY MATOR ; MATOR = HI-BYTE
RTS
*
CYC OFF
*
MKAND DS 1
MATOR DS 1
MSIGN DS 1
*
********************************
* WELCOME MESSAGE *
********************************
*
* PRINT OUT WELCOME TEXT AS SHAPES ON SCREEN
*
WLCMTXT LDX #$03
JSR HCOLOR
STX $F9 ; SET ROT = 0
LDA #$01
STA $E7 ; SET SCALE = 1
LDX #$00
TXTLOOP LDA TXTDAT,X
BEQ TLP2 ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #26 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #09 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX XREGDUMP
INX
BNE TXTLOOP
*
TLP2 LDX #$00
TXTLOOP2 LDA TXTDAT2,X
BEQ SUDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STX XREGDUMP ; SAVE X-REG COUNTER STATUS
TXA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAX ; MOVE X-POS TO X-REG
STX SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
*
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
*
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
LDX XREGDUMP
INX
BNE TXTLOOP2
SUDONE RTS
*
* TEXT MESSAGES WHEN LOADING 3D-OBJECTS
*
TXTOB1 LDA #TXTDAT3
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB2 LDA #TXTDAT4
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB3 LDA #TXTDAT5
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB4 LDA #TXTDAT6
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
TXTOB5 LDA #TXTDAT7
STA TXTPTR+1
JSR DLTTXT
JMP PRTTXT ; PRINT MESSAGE
*
PRTTXT LDY #$00
LDX #$03
JSR HCOLOR ; SET HCOLOR = 3
TXTLOOP3 LDA (TXTPTR),Y
BEQ TXTDONE ; STOP WHEN $00 IS READ
STA SHPDUMP ; SAVE SHAPE-NUMBER
STY YREGDUMP ; SAVE X-REG COUNTER STATUS
TYA ; MOVE CHAR POSITION TO ACCU
ASL ; CHAR-POS * 8 PIXEL
ASL ; EACH CHAR NEEDS 8 PIXEL
ASL ; SPACING
CLC
ADC #18 ; ADD X-OFFSET
TAY ; MOVE X-POS TO Y-REG
TAX ; ALSO TO X-REG
STY SHXPOS ; SAVE SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #32 ; DRAW ON SCREEN 1
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
LDX SHXPOS ; GET SHAPE X-POS
LDY #$00 ; HIGH-BYTE = 0
LDA #188 ; Y-OFFSET FOR TEXT OUTPUT
JSR HPOSN ; POSITION THE CURSOR
LDX SHPDUMP ; RETRIEVE SHAPE-NUMBER
JSR SHNUM ; GET SHAPE ADRESS
LDA #64 ; DRAW ON SCREEN 2
STA $E6
LDA #$00 ; SET ROT = 0
JSR SHDRAW ; DRAW SHAPE
LDY YREGDUMP
INY
BNE TXTLOOP3
TXTDONE RTS
*
TXTDAT HEX 292231313A01151135
HEX 2901232A33352925223A
HEX 012231312D26013E3C
HEX 00
*
TXTDAT2 HEX 450114250E25262E3001
HEX 0E012E0F28302D30
HEX 2E2326242C01131112
HEX 18014500
*
TXTDAT3 HEX 2D3022252A2F28013529
HEX 2601352635332226252633
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT4 HEX 2D3022252A2F28013529
HEX 2601362E2333262D2D22
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT5 HEX 2D3022252A2F28013529
HEX 2601342A2E312D260124362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT6 HEX 2D3022252A2F28013529
HEX 2601352635332224362326
HEX 0F0F0F010101010101
HEX 010100
*
TXTDAT7 HEX 2D3022252A2F28013529
HEX 2601243623260135382A2F34
HEX 0F0F0F010101010101
HEX 010100
*
LCNT DS 1
XREGDUMP DS 1
YREGDUMP DS 1
SHPDUMP DS 1
SHXPOS DS 1
*
* DELETE BOTTOM TEXT
*
DLTTXT LDX #$00
JSR HCOLOR ; HCOLOR = 0
LDA ASCR
DLTSTRT LDA #180
STA YDELROW ; Y OF LINE TO DELETE
DLTLOOP LDA #32
STA $E6 ; DELETE ON SCREEN 1
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
LDA #64
STA $E6 ; DELETE ON SCREEN 2
LDX #$02
LDY #$00
LDA YDELROW
JSR HPOSN
LDA #$15
LDX #$01
LDY YDELROW
JSR HLIN
INC YDELROW
LDA YDELROW
CMP #189 ; LINE 189 REACHED?
BCC DLTLOOP ; NO -> DELETE NEXT LINE
DLTEND RTS ; END OF LOOP
*
YDELROW DS 1
*
********************************
* LOAD 3D-OBJECTS IN MEMORY *
********************************
*
LOAD1 JSR TXTOB1 ; PRINT LOADING MESSAGE
LOAD01 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT1.3D,A$7200"
HEX 8D00
RTS
*
LOAD2 JSR TXTOB2
LOAD02 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT2.3D,A$7200"
HEX 8D00
RTS
*
LOAD3 JSR TXTOB3
LOAD03 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT3.3D,A$7200"
HEX 8D00
RTS
*
LOAD4 JSR TXTOB4
LOAD04 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT4.3D,A$7200"
HEX 8D00
RTS
*
LOAD5 JSR TXTOB5
LOAD05 LDA #$8D ; LOAD 3D-OBJECT 1 INTO MEMORY
JSR COUT
JSR PRINT
HEX 84
ASC "BLOAD OBJECT5.3D,A$7200"
HEX 8D00
RTS
*
PRINT PLA
STA PTR
PLA
STA PTR+1
LDY #$01
P0 LDA (PTR),Y
BEQ PFIN
JSR COUT
INY
BNE P0
CHK
*
PFIN CLC
TYA
ADC PTR
STA PTR
LDA PTR+1
ADC #$00
PHA
LDA PTR
PHA
PEXIT RTS
*
LST OFF
*
CHK
*