	ORG	$3A00,$A800
	JMP	DEMO

*************************************
*				*
*   V E C T O R    S C R O L L E R	*
*				*
*	  A simple demo by  	*
*				*
*      BEWESOFT - Jiri Bernasek	*
*				*
*    Finished in Prague, 93-02-15	*
*				*
*************************************

** Maximal speed:
CAS	EPZ	5

** Music...
MPINIT	EQU	$41CE	;Initialize
MPPLAY	EQU	$41CE+3	;Play
MUSIC	EQU	$4800	;Song data

** Text adress
TEXT	EQU	$5300

** Variables...

X1	EQU	$3900	;Parameters
X2	EQU	X1+1	;of DRAW
Y1	EQU	X2+1	;routine
Y2	EQU	Y1+1

OBRAZ	EQU	Y2+1	;#of active
*			;screen
BASET	EQU	OBRAZ+1	;fine pos.
TXOF	EQU	BASET+1	;pos.in txt

*Working variables of scroller
TBOF	EQU	TXOF+1	;Position
*			;in scroll
DFOF	EQU	TBOF+1	;Pos. in
*			;definition
*			;of letter
KRTX	EQU	DFOF+1

TIMER	EQU	KRTX+1	;Timer...

** Zero-page (0,1 used by music!)

*Working variables of DRAW-routine
DX	EPZ	3 ;Difference X
DY	EPZ	4 ;Difference Y
HDXDY	EPZ	5 ;Value DX-DY
COUNT	EPZ	6 ;Counter of points
F	EPZ	7 ;F value

** Tables in zero-page!!
BITM	EPZ	8	;Table of
*			;8 points
*			;in a byte
ZTAB	EPZ	$10	;Look-up
*			;table for
*			;actual
*			;screen!
*			(240 bytes)

** Tables...
XT1	EQU	$3000	;Tables of
YT1	EQU	$3080	;positions
XT2	EQU	$3100	;on the
YT2	EQU	$3180	;screen...
XT3	EQU	$3200
YT3	EQU	$3280
XT4	EQU	$3300
YT4	EQU	$3380
XT5	EQU	$3400
YT5	EQU	$3480

DEFS	EQU	$3500	;Defs. of
*			;letters

** Screen memory
VRAM1	EQU	$B100
VRAM2	EQU	$A100
VRAM3	EQU	$2100

** Dsplay list

DL	DFB	112,112,112

	DFB	13+64	;Picture
	DFW	$5000	;"BEWESOFT"
	DFB 13,13,13,13,13,13,13,13
	DFB 13,13,13,13,13,13,13,13
	DFB 13,13,13,13,13,13,13

	DFB 112,112,112

	DFB	15+64	;Main
DLLM	DFW	VRAM1	;screen

	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15

	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15

	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15

	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15,15
	DFB 15,15,15,15,15,15,15

	DFB	65
	DFW	DL

** DRAW routine!
* (Inputs: X1,X2,Y1,Y2)

DRAW	LDA	X2
	CMP	X1
	BCS	DRAW2

	LDX	X1	;If X2<X1
	LDY	Y1	;(the line
	LDA	X2	;is going
	STA	X1	;left),
	LDA	Y2	;we'll swap
	STA	Y1	;start and
	STX	X2	;end of the
	STY	Y2	;line

DRAW2	LDA	X1	;Starting
	LSR		;X-position
	LSR		;(bytes)
	LSR		;to the 'Y'
	TAY		;register

	LDA	X1	;Starting
	AND	#7	;X-position
	EOR	#7	;(bits) to
	TAX		;'X' reg.

	LDA	Y2	;If Y2<Y1
	CMP	Y1	;(line is
	BCC	DRAW3	;going up),
*			go to DRAW3

	LDA	X2	;Calculate
	SEC		;difference
	SBC	X1	;between
	STA	DX	;start and
*			;end of the
	LDA	Y2	;line
	SEC
	SBC	Y1
	STA	DY

	LDA	DX	;And now
	SEC		;the value
	SBC	DY	;DX-DY
	STA	HDXDY

	LDA	DX	;If DX>DY,
	CMP	DY	;it is a
	BCS	DRAW5H	;horizontal
*			;line

	LDA	DY	;Set number
	STA	COUNT	;of points
	INC	COUNT

	LSR		;And F
	STA	F	;value

	LDA	Y1	;Set the
	ASL		;right 'Y'
	CLC		;into the
	ADC	#ZTAB	;routine
	STA	DRAW6V+1
	STA	D6V2+1

	JMP	DRAW6V	;And draw!

** "Horizontal" lines going down

DRAW5H	LDA	DX	;Set number
	STA	COUNT	;of points
	INC	COUNT

	LSR		;And F
	STA	F	;value

	LDA	Y1	;Set the
	ASL		;right 'Y'
	CLC		;into the
	ADC	#ZTAB	;routine
	STA	DRAW6H+1
	STA	D6H2+1

	JMP	DRAW6H	;And draw!

** Lines going up...

DRAW3	LDA	X2	;Calculate
	SEC		;difference
	SBC	X1	;between
	STA	DX	;start and
*			;end of the
	LDA	Y1	;line
	SEC
	SBC	Y2
	STA	DY

	LDA	DX	;And the
	SEC		;value
	SBC	DY	;DX-DY
	STA	HDXDY

	LDA	DX	;If DX>DY,
	CMP	DY	;it is a
	BCS	DRAW4H	;horizontal
*			;line

	LDA	DY	;Set number
	STA	COUNT	;of points
	INC	COUNT

	LSR		;And F
	STA	F	;value

	LDA	Y1	;Set the
	ASL		;right 'Y'
	CLC		;into the
	ADC	#ZTAB	routine
	STA	DRAW7V+1
	STA	D7V2+1

	JMP	DRAW7V	;And draw!

** "Horizontal" lines going up

DRAW4H	LDA	DX	;Set number
	STA	COUNT	;of points
	INC	COUNT

	LSR		;And F
	STA	F	;value

	LDA	Y1	;Set the
	ASL		;right 'Y'
	CLC		;into the
	ADC	#ZTAB	;routine
	STA	DRAW7H+1
	STA	D7H2+1

	JMP	DRAW7H	;And draw!

** The main draw-routines...

** "Horizontal" lines going down

DRAW6H	LDA	(0),Y	;Display
	ORA	BITM,X	;one point
D6H2	STA	(0),Y

	LDA	F	;Finish
	SEC		;previous
	SBC	HDXDY	;calculati-
*			; on

* Now A=-F(X+1,Y+0.5)

	BCS	HODI7	;-F>0 =>
*			;Diagonal
*			;step

* Horizontal step

* -F((X+1)+1,Y+0.5)=-F(X+1,Y+0.5)+DY,
* but in the next step we'll calculate
* -F(X+1,Y+0.5)+DY-DX (It's the
* calculation for diagonal step).
* So, we need to add DX now!

	ADC	DX
	STA	F
	JMP	HODIL

* Diagonal step...

HODI7	STA	F

	CLC		;Move to
	LDA	DRAW6H+1	;the next
	ADC	#2	;line
	STA	DRAW6H+1
	STA	D6H2+1

* Move to the next X position

HODIL	DEX		;Next pos.
	BPL	HODIL2	;in byte

	LDX	#7	;Restore...
	INY		;And next
*			;byte!

HODIL2	DEC	COUNT	;Next point
	BNE	DRAW6H

	RTS

** "Vertical" lines going down

DRAW6V	LDA	(0),Y	;Display
	ORA	BITM,X	;one point
D6V2	STA	(0),Y

	LDA	DRAW6V+1	;Move to
	CLC		;the next
	ADC	#2	;line
	STA	DRAW6V+1
	STA	D6V2+1

	LDA	F	;Calcula-
	CLC		;tions...
	ADC	HDXDY

	BCS	VEN6

	ADC	DY
	STA	F

	JMP	HODILV

VEN6	STA	F

	DEX
	BPL	HODILV

	LDX	#7

	INY

HODILV	DEC	COUNT
	BNE	DRAW6V

	RTS

** "Horizontal" lines going up

DRAW7H	LDA	(0),Y	;Display
	ORA	BITM,X	;one point
D7H2	STA	(0),Y

	LDA	F	;Calcula-
	SEC		;tions...
	SBC	HDXDY

	BCS	HODI7B

	ADC	DX
	STA	F

	JMP	HODILB

HODI7B	STA	F

	SEC		;Move to
	LDA	DRAW7H+1	;the line
	SBC	#2	;above
	STA	DRAW7H+1
	STA	D7H2+1

HODILB	DEX
	BPL	HODIL2B

	LDX	#7

	INY

HODIL2B	DEC	COUNT
	BNE	DRAW7H

	RTS

** "Vertical" lines going up

DRAW7V	LDA	(0),Y	;Display
	ORA	BITM,X	;one point
D7V2	STA	(0),Y

	LDA	DRAW7V+1	;Move to
	SEC		;the line
	SBC	#2	;above
	STA	DRAW7V+1
	STA	D7V2+1

	LDA	F	;Calcula-
	CLC		;tions...
	ADC	HDXDY

	BCS	VEN6B

	ADC	DY
	STA	F

	JMP	HODILVB

VEN6B	STA	F

	DEX
	BPL	HODILVB

	LDX	#7

	INY

HODILVB	DEC	COUNT
	BNE	DRAW7V

	RTS

** Initialize the DRAW-routine...

INIT	LDX	#7	;Initialize
	LDA	#$80	;bit-map
I2	STA	BITM,X	;table
	LSR
	DEX
	BPL	I2

* Look-up table for screen 1...

	LDX	#0
	LDA	#VRAM1:L
	LDY	#VRAM1:H

I3	STA	$B000,X
	PHA
	TYA
	STA	$B001,X
	PLA

	CLC
	ADC	#32
	BCC	I4
	INY

I4	INX
	INX
	CPX	#240
	BCC	I3

* Look-up table for screen 2...

	LDX	#0
	LDA	#VRAM2:L
	LDY	#VRAM2:H

I5	STA	$A000,X
	PHA
	TYA
	STA	$A001,X
	PLA

	CLC
	ADC	#32
	BCC	I6
	INY

I6	INX
	INX
	CPX	#240
	BCC	I5

* Look-up table for screen 3...

	LDX	#0
	LDA	#VRAM3:L
	LDY	#VRAM3:H

I7	STA	$2000,X
	PHA
	TYA
	STA	$2001,X
	PLA

	CLC
	ADC	#32
	BCC	I8
	INY

I8	INX
	INX
	CPX	#240
	BCC	I7
*
	RTS

** Initialize screen 1...

CLS1	LDX	#0
	TXA

CLS1B	STA	$B100,X	;Clear
	STA	$B200,X	;screen 1
	STA	$B300,X
	STA	$B400,X
	STA	$B500,X
	STA	$B600,X
	STA	$B700,X
	STA	$B800,X
	STA	$B900,X
	STA	$BA00,X
	STA	$BB00,X
	STA	$BC00,X
	STA	$BD00,X
	STA	$BE00,X
	STA	$BF00,X
	DEX
	BNE	CLS1B

	LDX	#239	;Copy the
CLS1C	LDA	$B000,X	;table of
	STA	ZTAB,X	;screen 1
	DEX		;into main
	CPX	#255	;look-up
	BNE	CLS1C	;table

	RTS

** The same for screen 2...

CLS2	LDX	#0
	TXA

CLS2B	STA	$A100,X
	STA	$A200,X
	STA	$A300,X
	STA	$A400,X
	STA	$A500,X
	STA	$A600,X
	STA	$A700,X
	STA	$A800,X
	STA	$A900,X
	STA	$AA00,X
	STA	$AB00,X
	STA	$AC00,X
	STA	$AD00,X
	STA	$AE00,X
	STA	$AF00,X
	DEX
	BNE	CLS2B

	LDX	#239
CLS2C	LDA	$A000,X
	STA	ZTAB,X
	DEX
	CPX	#255
	BNE	CLS2C

	RTS

** And for screen 3...

CLS3	LDX	#0
	TXA

CLS3B	STA	$2100,X
	STA	$2200,X
	STA	$2300,X
	STA	$2400,X
	STA	$2500,X
	STA	$2600,X
	STA	$2700,X
	STA	$2800,X
	STA	$2900,X
	STA	$2A00,X
	STA	$2B00,X
	STA	$2C00,X
	STA	$2D00,X
	STA	$2E00,X
	STA	$2F00,X
	DEX
	BNE	CLS3B

	LDX	#239
CLS3C	LDA	$2000,X
	STA	ZTAB,X
	DEX
	CPX	#255
	BNE	CLS3C

	RTS

** Initialize I/O ports...

HWINI	LDA	#0	;Disable
	CLD		;interrupts
	SEI		;DMA and
	STA	54286	;PMG
	STA	$D400
	STA	53277

	LDA	#$FF	;BASIC-ROM
	STA	$D301	;off, cold
	STA	580	;RESET

	LDA	#0	;Clear
	LDX	#8	;GTIA and
HW2	STA	$D000,X	;POKEY
	STA	$D008,X
	STA	$D010,X
	STA	$D016,X
	STA	$D200,X
	DEX
	BPL	HW2

	LDY	#VBI:L	;Set the
	LDX	#VBI:H	;adress of
	LDA	#6	;VBI
	JSR	$E45C

	JSR	CLS3	;Initialize
*			;screen 3,
	LDA	#2	;and turn
	STA	OBRAZ	;to it

	LDY	#MUSIC:H	;Initialize
	LDX	#MUSIC:L	;music
	JSR	MPINIT

	LDA	#$92	;Set colors
	STA	$D01A
	STA	$D018
	LDA	#$48
	STA	$D016
	LDA	#$4C
	STA	$D017

	LDA	#64	;Enable VBI
	STA	54286

	RTS

** VBI routine...

VBIT1	DFW	VRAM1,VRAM2,VRAM3

VBI	LDA	#DL:L	;Set adress
	STA	$D402	;of DL
	LDA	#DL:H
	STA	$D403

	LDA	#33	;Enable DMA
	STA	$D400

	LDA	OBRAZ	;Switch to
	ASL		;correct
	TAX		;screen#
	LDA	VBIT1,X
	STA	DLLM
	LDA	VBIT1+1,X
	STA	DLLM+1

	LDA	TIMER	;Support
	BEQ	VBIEX	;for timer
	DEC	TIMER

VBIEX	JSR	MPPLAY	;Play music

	JMP	$E462	;Exit...

** The main demo-program...

DEMO	JSR	HWINI	;Initialize
*			;hardware
	JSR	INIT	;and DRAW
*			;routine

	JSR	SCROLIN	;Initialize*			;text-
*			;scroller

	LDA	#CAS	;Initialize
	STA	TIMER	;timer

** Main loop

DEML	JSR	CLS1	;Intialize
*			;screen 1
	JSR	KRESLI	;Paint text
	LDA	#0	;Switch to
	STA	OBRAZ	;this scrn.

	JSR	CLS2	;Initialize
*			;screen 2
	JSR	KRESLI	;Paint text
	LDA	#1	;Switch to
	STA	OBRAZ	;this scrn.

	JSR	CLS3	;Initialize
*			;screen 3
	JSR	KRESLI	;Paint text
	LDA	#2	;Switch to
	STA	OBRAZ	;this scrn.

	JMP	DEML	;And again!

** Initialize scroller...

SCROLIN	LDA	#125	;Position
	STA	BASET	;in letter

	LDA	#TEXT:L	;Adress of
	STA	TLDA+1	;text
	LDA	#TEXT:H
	STA	TLDA+2

	RTS

** Paint the text!

KRESLI	LDA	#0	;Pointer in
	STA	TXOF	;the text

	LDA	BASET	;Position
	STA	TBOF	;in the
*			;table of
*			;screen-
*			;-positions

KRE1	LDX	TXOF
TLDA	LDA	$FFFF,X	;Get letter

	CMP	#31	;End of
	BNE	KRE2	;text ?

	LDA	#TEXT:L	;Yes...
	STA	TLDA+1	;Back to
	LDA	#TEXT:H	;the begin!
	STA	TLDA+2
	JMP	KRE1
*
KRE2	BCC	KRE2B	;code<32?
	CMP	#96	;or >96?
	BCC	KRE3
*			;Wrong code
KRE2B	LDA	#32	;->space

KRE3	SEC		;Internal
	SBC	#32	;code...
	STA	DFLD+1

	LDA	#0	;Position
	ASL	DFLD+1	;in the
	ASL	DFLD+1	;table=
	ASL	DFLD+1	;code*16
	ROL
	ASL	DFLD+1
	ROL

	CLC
	ADC	#DEFS:H
	STA	DFLD+2
*
	LDA	#0	;Position
	STA	DFOF	;in the
*			;definition
*			;of letter

KRE4	JSR	DFLD0	;Get code
*			;of start
*			;of a line
*			;from def.
*			;of letter

	BMI	KRE5	;End of
*			;def.?

	JSR	KRETA	;Get actual
*			;position
	STX	X1	;from the
	STY	Y1	;table

	JSR	DFLD0	;And the
	BMI	KRE5	;same for
	JSR	KRETA	;the end
	STX	X2	;of the
	STY	Y2	;line...

	JSR	DRAW	;Draw line!

	LDA	DFOF	;End of
	CMP	#16	;def.?
	BCC	KRE4

KRE5	INC	TXOF	;Next
*			;letter

	LDA	TBOF	;Next pos.
	SEC		;in table
	SBC	#3	;of screen-
	STA	TBOF	;-positions

	BCC	KRE5B	;<0 -> End

	CMP	#2	;>2 -> Cont
	BCS	KRE1
*
KRE5B	INC	BASET	;Next pos.
	BPL	KRE7	;in letter

	LDA	#125	;End ->
	STA	BASET	;restore it

	INC	TLDA+1	;And move
	BNE	KRE7	;to next
	INC	TLDA+2	;letter

KRE7	LDA	TIMER	;Wait till
	BNE	KRE7	;TIMER=0
*(If there are only few letters on the
* screen, the scroll will not speed up
* too much now...)

	LDA	#CAS	;Restore
	STA	TIMER	;the timer

	RTS

** Get one byte from definition of
** a letter

DFLD0	LDX	DFOF	;Position
	INC	DFOF	;in def.
DFLD	LDA	$FFFF,X	;Get byte
	RTS

** Convert the byte from letter-def.
** into real screen-position...

KRETA	PHA
	LSR
	LSR
	AND	#7	;# of table
	ORA	#$30
	STA	KRTL+2

	PLA		;Offset
	AND	#3	;in the
	STA	KRTX	;table

	LDA	TBOF	;Add pos.
	SEC		;in whole
	SBC	KRTX	;scroll-
	TAY		;-line

	JSR	KRTL	;Get X-pos.
	TAX

	TYA		;Switch to
	ORA	#128	;second
	TAY		;half of
*			;the table

	JSR	KRTL	;Get Y-pos.
	TAY
	RTS

** Get a position from table...

KRTL	LDA	$FF00,Y
	RTS

** And that's all!!
���������������������������������������������������������������������