In this section I would like to demonstrate possible steps to optimize vectorlist drawing.
The shown possible steps are not ment to be "complete", exclusively right or particulary engenious.
Each scenario of ones own coding base provides grounds for other or more specific optimization technics.
I will show different versions of printing a vectorlist, which in each version step will be slightly more optimized in specific ways.
The demonstration program(s) will draw a vectorlist which represents a "hut" like:
Note:
Below given cycle measurement may be different to you measurements. To have exactly the same measurements you must use exactly the same Vide configuration - which even I can't remember right now - but the relation of the values should be correct!

Hut
(The hut is pretty small, but as you will see, drawing a "small" list is easier to optimize - also in many games drawing many small objects is the predominant scenario)
Basis:
;*****************************************************
; DEFINE SECTION
;*****************************************************
; load vectrex bios routine definitions
INCLUDE "VECTREX.I" ; vectrex function includes
;*****************************************************
; Variable / RAM SECTION
;*****************************************************
; insert your variables (RAM usage) in the BSS section
; user RAM starts at $c880
BSS
ORG $c880 ; start of our ram space
;*****************************************************
; HEADER SECTION
;*****************************************************
; The cartridge ROM starts at address 0
CODE
ORG 0
; the first few bytes are mandatory, otherwise the BIOS will not load
; the ROM file, and will start MineStorm instead
DB "g GCE 1998", $80 ; "g' is copyright sign
DW music1 ; music from the rom
DB $F8, $50, $20, -$80 ; hight, width, rel y, rel x (from 0,0)
DB "DRAW LINES V1", $80 ; some game information, ending with $80
DB 0 ; end of game header
;*****************************************************
; CODE SECTION
;*****************************************************
; here the cartridge program starts off
main:
JSR Wait_Recal ; Vectrex BIOS recalibration
JSR Intensity_5F ; Sets the intensity of the
; vector beam to $5f
LDA #$b0 ; scalefactor
STA VIA_t1_cnt_lo
LDA #$00 ; position relative Y
LDB #$00 ; position relative X
JSR Moveto_d ; sets up VIA control register after a wait recal
LDX #vData ; address of string
JSR Draw_VLc ; Vectrex BIOS print routine
BRA main ; and repeat forever
;*****************************************************
; DATA SECTION
;*****************************************************
vData = VectorList
VectorList:
DB +$07 ; number of lines to draw
DB +$00, +$06 ; draw to y, x
DB +$07, +$00 ; draw to y, x
DB +$05, -$03 ; draw to y, x
DB -$05, -$03 ; draw to y, x
DB -$07, +$00 ; draw to y, x
DB +$07, +$06 ; draw to y, x
DB +$00, -$06 ; draw to y, x
DB -$07, +$06 ; draw to y, x
In the above version (for demonstration purposes) I used a large scale factor and small vector strengths. Using a small scale factor and large vector strength results in huge optimization effects.
The scale factor and strength changes are not 1:1 - you have to experiment to get the same "sizes" of the resulting lists.
In the example I changed the scale factor from $b0 to $06, and multiplied each (original) strength by 18.
;*****************************************************
; DEFINE SECTION
;*****************************************************
; load vectrex bios routine definitions
INCLUDE "VECTREX.I" ; vectrex function includes
;*****************************************************
; Variable / RAM SECTION
;*****************************************************
; insert your variables (RAM usage) in the BSS section
; user RAM starts at $c880
BSS
ORG $c880 ; start of our ram space
;*****************************************************
; HEADER SECTION
;*****************************************************
; The cartridge ROM starts at address 0
CODE
ORG 0
; the first few bytes are mandatory, otherwise the BIOS will not load
; the ROM file, and will start MineStorm instead
DB "g GCE 1998", $80 ; "g' is copyright sign
DW music1 ; music from the rom
DB $F8, $50, $20, -$80 ; hight, width, rel y, rel x (from 0,0)
DB "DRAW LINES V2", $80 ; some game information, ending with $80
DB 0 ; end of game header
;*****************************************************
; CODE SECTION
;*****************************************************
; here the cartridge program starts off
main:
JSR Wait_Recal ; Vectrex BIOS recalibration
JSR Intensity_5F ; Sets the intensity of the
; vector beam to $5f
LDA #$06 ; scalefactor
STA VIA_t1_cnt_lo
LDA #$00 ; position relative Y
LDB #$00 ; position relative X
JSR Moveto_d ; sets up VIA control register after a wait recal
LDX #vData ; address of string
JSR Draw_VLc ; Vectrex BIOS print routine
BRA main ; and repeat forever
;*****************************************************
; DATA SECTION
;*****************************************************
BLOW UP = 18
vData = VectorList
VectorList:
DB +$07 ; number of lines to draw
DB +$00*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$00*BLOW_UP, -$06*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
This version is a step "in between". Nothing really changed, only the call of "JSR Draw VLc" was replaced with a macro call of exactly the same routine.
;*****************************************************
; DEFINE SECTION
;*****************************************************
; load vectrex bios routine definitions
INCLUDE "VECTREX.I" ; vectrex function includes
DRAW_VLC macro
direct $d0 ; following code uses d0
LDA ,X+
Draw_VL_a_macro?
STA $C823
LDD ,X
STA <VIA_port_a ;Send Y to A/D
CLR <VIA_port_b ;Enable mux
LEAX 2,X ;Point to next coordinate pair
NOP ;Wait a moment
INC <VIA_port_b ;Disable mux
STB <VIA_port_a ;Send X to A/D
LDD #$FF00 ;Shift reg=$FF (solid line), T1H=0
LF3ED\?:
STA <VIA_shift_reg ;Put pattern in shift register
STB <VIA_t1 cnt_hi ;Set T1H (scale factor?)
LDD #$0040 ;B-reg = T1 interrupt bit
LF3F4\?:
BITB <VIA_int_flags ;Wait for T1 to time out
BEQ LF3F4\?
NOP ;Wait a moment more
STA <VIA_shift_reg ;Clear shift register (blank output)
LDA $C823 ;Decrement line count
DECA
BPL Draw_VL_a_macro\? ;Go back for more points
JSR Check0Ref ;Reset zero reference if necessary
endm
;*****************************************************
; Variable / RAM SECTION
;*****************************************************
; insert your variables (RAM usage) in the BSS section
; user RAM starts at $c880
BSS
ORG $c880 ; start of our ram space
;*****************************************************
; HEADER SECTION
;*****************************************************
; The cartridge ROM starts at address 0
CODE
ORG 0
; the first few bytes are mandatory, otherwise the BIOS will not load
; the ROM file, and will start MineStorm instead
DB "g GCE 1998", $80 ; "g' is copyright sign
DW music1 ; music from the rom
DB $F8, $50, $20, -$80 ; hight, width, rel y, rel x (from 0,0)
DB "DRAW LINES V3", $80 ; some game information, ending with $80
DB 0 ; end of game header
;*****************************************************
; CODE SECTION
;*****************************************************
; here the cartridge program starts off
main:
JSR Wait_Recal ; Vectrex BIOS recalibration
JSR Intensity_5F ; Sets the intensity of the
; vector beam to $5f
LDA #$06 ; scalefactor
STA VIA_t1_cnt_lo
LDA #$00 ; position relative Y
LDB #$00 ; position relative X
JSR Moveto_d ; sets up VIA control register after a wait recal
LDX #vData ; address of string
DRAW_VLC ; Macro print routine
BRA main ; and repeat forever
;*****************************************************
; DATA SECTION
;*****************************************************
BLOW UP = 18
vData = VectorList
VectorList:
DB +$07 ; number of lines to draw
DB +$00*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$00*BLOW_UP, -$06*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
The above introduced macro was changed to a manualy optimized version.
;*****************************************************
; DEFINE SECTION
;*****************************************************
; load vectrex bios routine definitions
INCLUDE "VECTREX.I" ; vectrex function includes
DRAW_VLC macro
direct $d0 ; following code uses d0
LDD ,X++ ;
STA $C823 ;
CLRA
_DRAW_VLA\?:
STD VIA_port_b
LDB ,X+
INC VIA_port_b ;Disable mux
STB VIA_port_a ;Send X to A/D
DEC VIA_shift_reg ;Put pattern in shift register
STA VIA_t1_cnt_hi ;enable timer 1
LDB ,X+ ; 6
DEC $C823 ; 7
BEQ DRAW_END\? ; 3 Go back for more points
LDA #$40 ;B-reg = T1 interrupt bit
LF_1\?:
BITA VIA_int_flags ;Wait for T1 to time out
BEQ LF_1\? ;
CLRA ;Wait a moment more
STA VIA_shift_reg ;Clear shift register (blank output)
BRA DRAW_VLA\? ; 3
_DRAW_END\?:
LDA #$40 ;B-reg = T1 interrupt bit
LF_2\?:
BITA VIA_int_flags ;Wait for T1 to time out
BEQ LF_2\? ;
CLRA ;Wait a moment more
STA VIA_shift_reg
; one more round
STD VIA_port_b
LDB ,X+
INC VIA_port_b ;Disable mux
STB VIA_port_a ;Send X to A/D
DEC VIA_shift_reg ;Put pattern in shift register
STA VIA_t1_cnt_hi ;enable timer 1
LDA #$40 ;B-reg = T1 interrupt bit
LF_3?:
BITA VIA_int_flags ;Wait for T1 to time out
BEQ LF_3\?
CLR VIA_shift_reg ;Clear shift register (blank output)
endm
;*****************************************************
; Variable / RAM SECTION
;*****************************************************
; insert your variables (RAM usage) in the BSS section
; user RAM starts at $c880
BSS
ORG $c880 ; start of our ram space
;*****************************************************
; HEADER SECTION
;*****************************************************
; The cartridge ROM starts at address 0
CODE
ORG 0
; the first few bytes are mandatory, otherwise the BIOS will not load
; the ROM file, and will start MineStorm instead
DB "g GCE 1998", $80 ; "g' is copyright sign
DW music1 ; music from the rom
DB $F8, $50, $20, -$80 ; hight, width, rel y, rel x (from 0,0)
DB "DRAW LINES V4", $80 ; some game information, ending with $80
DB 0 ; end of game header
;*****************************************************
; CODE SECTION
;*****************************************************
; here the cartridge program starts off
main:
JSR Wait_Recal ; Vectrex BIOS recalibration
JSR Intensity_5F ; Sets the intensity of the
; vector beam to $5f
LDA #$06 ; scalefactor
STA VIA_t1_cnt_lo
LDA #$00 ; position relative Y
LDB #$00 ; position relative X
JSR Moveto_d ; sets up VIA control register after a wait recal
LDX #vData ; address of string
DRAW_VLC ; Macro print routine
BRA main ; and repeat forever
;*****************************************************
; DATA SECTION
;*****************************************************
BLOW_UP = 18
vData = VectorList
VectorList:
DB +$07 ; number of lines to draw
DB +$00*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$00*BLOW_UP, -$06*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
The loop in the vector drawing was unrolled, and the actual drawing routine does not have a wait loop anymore, since we now that the length of the loop (= scalefactor) is 6. We can use the information, that we only draw for 6 cycles, to NOT wait for these 6 cycles to finish - we know how many cycles our instructions take.
To do the loop unrolling and some of the math involved (jump into a unrolled vector drawing routine) we changed the first parameter of the vectorlist to have a unrolled offset counter instead of the vectorlist length.
The maximum unrolled loop in this version is 11 vectors (maximum vectorlist size).
The size of the header (10) and one line (16) is manually computed, but could also be automatically gotten from address "math".
;*****************************************************
; DEFINE SECTION
;*****************************************************
; load vectrex bios routine definitions
INCLUDE "VECTREX.I" ; vectrex function includes
ONE_LINE_LENGTH EQU 16
LENGTH_OF_HEADER EQU (4+2+2+2)
MAX_LINE_NUM EQU 23
ONE_LINE_DRAW macro ; cycles
INC VIA_port_b ; [6] Disable mux
STB VIA_port_a ; [6] Send X to A/D
DEC VIA_shift_reg ; [6] Put pattern in shift register
CLR VIA_t1_cnt_hi ; [4] enable timer 1
LDD ,X++ ; [8] load Y coordinate to A, X coordinate to B
STA VIA_port_a ; [4] Send Y to A/D
CLR VIA_port_b ; [4] enable mux, thus y integrators are set to Y
CLR VIA_shift_reg ; [4] turn the lights off
endm
MY_SPRITE_DRAW_VLC_UNLOOP_SMALL macro
LDD ,X++ ;(2)
STA VIA_port_a ;(2) [4] Send Y to A/D
CLR VIA_port_b ;(2) [4] enable mux, thus y integrators are set to Y
JMP [i_jump] ;(4)
JUMP_INTO_ALL\?:
JUMP_INTO_11\?:
ONE_LINE_DRAW
JUMP_INTO_10\?:
ONE_LINE_DRAW
JUMP_INTO_09\?:
ONE_LINE_DRAW
JUMP_INTO_08\?:
ONE_LINE_DRAW
JUMP_INTO_07\?:
ONE_LINE_DRAW
JUMP_INTO_06\?:
ONE_LINE_DRAW
JUMP_INTO_05\?:
ONE_LINE_DRAW
JUMP_INTO_04\?:
ONE_LINE_DRAW
JUMP_INTO_03\?:
ONE_LINE_DRAW
JUMP_INTO_02\?:
ONE_LINE_DRAW
JUMP_INTO_01\?:
INC VIA_port_b ; [6] Disable mux
STB VIA_port_a ; [6] Send X to A/D
DEC VIA_shift_reg ; [6] Put pattern in shift register
CLR VIA_t1_cnt_hi ; [4] enable timer 1
NOP 3
endm
;*****************************************************
; Variable / RAM SECTION
;*****************************************************
; insert your variables (RAM usage) in the BSS section
; user RAM starts at $c880
BSS
ORG $c880 ; start of our ram space
;*****************************************************
; HEADER SECTION
;*****************************************************
; The cartridge ROM starts at address 0
CODE
ORG 0
; the first few bytes are mandatory, otherwise the BIOS will not load
; the ROM file, and will start MineStorm instead
DB "g GCE 1998", $80 ; "g' is copyright sign
DW music1 ; music from the rom
DB $F8, $50, $20, -$80 ; hight, width, rel y, rel x (from 0,0)
DB "DRAW LINES V5", $80 ; some game information, ending with $80
DB 0 ; end of game header
;*****************************************************
; CODE SECTION
;*****************************************************
; here the cartridge program starts off
main:
JSR Wait_Recal ; Vectrex BIOS recalibration
JSR Intensity_5F ; Sets the intensity of the
; vector beam to $5f
LDA #$06 ; scalefactor
STA VIA_t1_cnt_lo
LDA #$00 ; position relative Y
LDB #$00 ; position relative X
JSR Moveto_d ; sets up VIA control register after a wait recal
LDX #vData ; address of string
LDD ,X++ ; load offset of vector list draw
ADDD #(unloop_start_address0+LENGTH_OF_HEADER-12*ONE_LINE_LENGTH); 4=JMP [], 2=LDD ,X++
STD i_jump
unloop_start_address0:
MY_SPRITE_DRAW_VLC_UNLOOP_SMALL
NOP 2
CLR VIA_shift_reg ; [4] turn the lights off
BRA main ; and repeat forever
;*****************************************************
; DATA SECTION
;*****************************************************
BLOW UP = 18
vData = VectorList
VectorList:
DW (MAX LINE NUM-(7+1))*ONE LINE LENGTH
DB +$00*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$05*BLOW_UP, -$03*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$00*BLOW_UP; draw to y, x
DB +$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
DB +$00*BLOW_UP, -$06*BLOW_UP; draw to y, x
DB -$07*BLOW_UP, +$06*BLOW_UP; draw to y, x
- unfinished -