Drawing vectors - differently

Simply put vector drawing goes like this:

Less simple:
The way BIOS (and most other implementations) draw vectors is:
(drawing characters or raster data is slightly different)

A short via side explanation (for more in depth see "Vectrex internals → Analog").

Moving the beam internally is realized using integrator circuits which are connected to the deflection coils. Whether the integrators are integrating or not is controlled by a single "flag" (one BIT), which is called ~RAMP.

~RAMP is a zero active flag, meaning the integrators are WORKING when the ~RAMP flag equals zero, this is indicated by the "~" in front of the flag.

Switching the light on and off is internally nearly the same thing, the brightness of the light is set equally to the strength of the vectors [NOT using the blank flag], and the circuit telling the CRT to actually send a "strong" electron beam (which illuminates the phosphor coated tube) is not really that much different than the deflection coil circuits.
What the "~RAMP" signal is for moving - that is the "~BLANK" signal for light on off.
The ~BLANK is also a single (zero active) flag, which tells vectrex to switch the light off ~BLANK equals zero, or to switch the light on (~BLANK non zero).

To communicate the state of the flags (set/unset) VIA 6522 is used.

~RAMP flag is connected the seventh bit of VIA port B (in the following the short form of PB7 is used (Port B bit 7).

~BLANK flag is connected to the VIA Control line Port B 2 (in the following the short form CB2 is used (Controll line Port B 2))

As the name VIA (Versatile Interface Adapter) implies - there are more than one way to handle things. Via has a couple of control registers, that influence the way it behaves. In relation to the above two "flags" (PB7 = ~RAMP and CB2 = ~BLANK) following information is "interesting":

Default BIOS settings:
VIA register $b (auxiliary control register) is set to $98, which in bits is %10 0 110 00. (See also Vide documentaion: Vectrex internals→ VIA)

What this boils down to is the above described "less simple" way of drawing a vector.

Starting the timer 1 "automatically" starts moving the vector. Programatically writing "$ff" to the shift register switches the light on for every shift cycle following (~BLANK = 1 means the light is on).

When the timer t1 reaches zero, the vector automatically stops moving. Than one programatically has to switch the light of by writing 0 to the shift register.
(Note: it is better to do a
  sta via_shiftreg

than to do a
  clr via_shiftreg,
the speed (processor cycles) is the same, but doing a "clr via_shiftreg" also READS the shiftreg, which inherently starts shifting and does output at least one other shift cycle to CB2).

As you might notice, the switch light off using the above method always switches the light off after the moving stops - actually the light is switched off (due to instructions being not immediate) after some additional cycles (at least 4). Meaning the light is kept on for that number of cycles for to long!

You can see that on your vectrex, each vector has a brighter spot at its end, this is because the light is switched off a few cycles to late.


As you might have guessed with the above mentioning of "versatile" - you can also access the above flags differently.

One other ways to access both bits is to set them "manually".

Below given example (in X register given a Draw_VLc compatible vectorlist) draws vectors "manually" - meaning without using a timer and without using the shift register.

Following settings were used:
VIA register $b (auxiliary control register) is set to $00, which in bits is %00 0 000 00. (See also Vide documentaion: Vectrex internals→ VIA)

By setting the via auxiliary control register to above values, both flags can be set manually.

; setup fixdraw
        lda   ,x+            ; load the count of vectors to draw
        sta   tmp            ; and remember them somewhere
        LDA   #$81            
        sta   <VIA_port_b    ; mux disabled, ramp disables
        LDA   #$00            
        STA   <VIA_aux_cntl  ; Shift reg mode = 000 free disable, T1 PB7 disabled
        lda   #$ce
        STA   <VIA_cntl      ; ZERO disabled, and BLANK enabled
        ldd   ,x++           ; a = y, b = x
        STA   <VIA_port_a    ; Y → Send it to the D/A
        lda   #$80
        sta   <VIA_port_b    ; ramp disabled, mux enabled → to Y
        sta   <VIA_port_b    ; ramp disabled, mux disabled → to Y
        STB   <VIA_port_a    ; X → Send it to the D/A
        ldd   #$8101
        stb   <VIA_port_b    ; below are x cycles RAMP switched on!
        ldb   #$ee
        stb   <VIA_cntl      ; ZERO disabled, and BLANK disabled

        nop   10 ; DELAY

        sta   <VIA_port_b    ; disable ramp ; should again be $81
; and x +y cycles light switched on
        nop   2
        dec   tmp
        bpl   noEnd
        ldb   #$ce
        stb   <VIA_cntl      ; ZERO disabled, and BLANK enabled
        LDA   #$98
        STA   <VIA_aux_cntl

The line with "nop   10 ; DELAY" is responsible for the size of the resulting image (much like the scale factor).

Although the code above suggests otherwise in consideration of VIA internal timings - the above vector drawing done is (at least using my vectri) cycle exact. ~RAMP and ~BLANK are set and unset at the correct times, and there are no bright spots on either side of the drawn vectors. (~BLANK is switched off for 20 cycles longer than ~RAMP - I have no clue what VIA is doing in those 20 cycles!)

The timings given in above example have been experimentally gotten by trial an error using real life vectrex systems. While Vide is able to display the result correctly, emulation of VIA internal timing is not good enough to trust the emulator on timing experiments.