
                     Vectrex HP3000 Programming Notes
                      (Rev B - 21st March 1993)


     Author : Keith Wilkins

     email  : spike@trd.tmg.nec.co.jp  (until April 28th 1993)

              After this date I will be off the air until
              I get my act together and organize a private
              internet account for myself. Not too long I hope.


     Revision History:

              Rev A: 14/03/93 K.W  -  1st Draft, incomplete.
              Rev B: 21/03/93 K.W  -  2nd Draft, incomplete.



     If you find errors (Technical/Spelling/Grammar) in this document
     please mail me with a description of the error and I'll fix the file
     for the next revision, all spelling mistakes are copyright.

     I will welcome additions of new material, and credit the author
     in this preface section.

     Do you have documents describing the following devices:

                Vectrex DAC MC1408-P8
                6522PIA Software/Hardware Spec
                AY-3-8192 Software/Hardware Spec
                Source code to the Vectrex EXEC ROM

     I am having trouble locating these documents which is slowing down
     the compilation of this file, so if you have them or know of where
     to get them please let me know.





     Disclaimer:

     I feel that I have to add one of these, not because I want to, but
     just in case anyone does something stupid and then says its my
     fault.

     WARNING - The voltages generated on the CRT drive board are Very
               HIGH and Very dangerous, dont mess with the Vectrex
               hardware unless you know what you are doing.

     I take no responsibility for how you use this information. I also
     make no guarantees that any of the information contained herein is
     is correct.


System Memory Map
~~~~~~~~~~~~~~~~~

To save chips/money/space the vectrex memory is a little convoluted but
only uses 2 chips, one conatining four 2 input NAND gates and the other
containing four 2 input OR gates. Its a most admirable job considering
the number of gates used.


    0000-7fff   Cartridge ROM Space, the CART line is also gated with
                ~E to produce a signal that can be fed directly to the
                output enable of a ROM. This address range is not gated
                with the read-write line but this line is fed to the
                cartridge connector. (r/w)

    8000-C7FF   Unmapped space.

    C800-CFFF   Vectrex RAM Space 1Kx8, shadowed twice. (r/w)

    D000-D7FF   6522PIA shadowed 128 times (r/w)

    D800-DFFF   Dont use this area. Both the 6522 and RAM are selected
                in any reads/writes to this area.

    E000-FFFF   System ROM Space 8Kx8 (r/w)



6522A
~~~~~

This device is used to control all of the vectrex peripheral devices, such
as the Keypads, Vector generator, DAC, Sound chip, etc.

The A port is used as a BUS and goes directly to the DAC input and sound
chip input pins D0-D7. The DAC will output whatever value is on this
port.

The B Port is used in the following way:

    PB0 - SWITCH    Switch Control, enables/disables the analog multiplexer,
                    see Vector drawing hardware description

    PB1 - SEL0      Controls multiplexer channel select, see section on
    PB2 - SEL1      Vector drawing.

    PB3 - BC1       Chip Select Signal for the AY-3-8192 Sound Chip
    PB4 - BDIR      Read/Write Signal for the AY-3-8192 Sound Chip

    PB5 - COMPARE   Feedback from the OP-AMP that does the comparison
                    for calculation of analog joystick positions.

    PB6 - ???       This line is fed to the cartridge connector. It is
                    likely that this line was to have been used as a ROM
                    bank select for cartridges greater than 32K.

    PB7 - ~RAMP     This line controls part of the vector drawing
                    hardware, see later. It is an active LOW signal.

The 6522PIA Has a number of control lines that are sometimes used as
handshake lines as the can generate interrupts, but on the vectrex they
are used to control the vector drawing hardware

    CA1 - IO7       This line is connected to the IO7 line of the AY-3-8192
                    sound chip. My guess it is used to generate an
                    interrupt to the CPU. See the AY-3-8192 description
                    for more details on IO7.

    CA2 - ~ZERO     Connected to the integrators that form part of the
                    vector drawing hardware. This line will cause them
                    to be zero'd (both X and Y) and has the effect of
                    bringing the beam back to the centre of the CRT. It
                    is an active LOW signal. See Vector hardware section
                    for more info.

    CB1 - Not Connected

    CB2 - ~BLANK    This Active LOW signal is the BEAM ON/OFF signal
                    to the Vector drawing hardware, and is used to hide
                    the beam when it is being positioned for re-draw.
                    See Vector hardware section for more info.



Vector Drawing hardware
~~~~~~~~~~~~~~~~~~~~~~~

I apologise in advance for the patronising nature of some of the text in
this section, if you know it already ignore it it isnt aimed at you. The
text is aimed at computer literate people who may not have dabbled in
the fuzzy world of Digital/Analog interfacing.

When I use the word ASSERTED or ACTIVE state with reference to a signal
I an talking about the state in which it is active. ie RAMP is only
active when its LOW (ZERO) and INACTIVE when HIGH. INACTIVE or NEGATED
means the signal is not in the ACTIVE state. See the descriptions of the
different signals for what there particular active state is.

It will to understand this section if you have a copy of the Vector drawing
block diagram (see vector.gif).

The vector drawing circuit is a mixed analog/digital circuit, consisting
of the following parts. When the text says SET or CLEAR a line or
feature refer back to these descriptions of how to set-up the hardware
for a particular function:

1) The DAC. (Digital to Analog Convertor)

        This is the most crucial part of the Vector block. It is connected
        directly to PORT A of the 6522. (See 6522A Section for details
        on how to setup and write to PORT A). The DAC takes this 8 bit
        digital value and converts it into an analog signal proportional
        to the value of the byte presented to the DAC.

                DAC Vout = (PORTA - OFFSET) * Constant

        The range if the DAC output if from +?.??V to -?.??V in steps
        of ?.??V.

        Be warned there is NO enable control on the DAC so whatever value
        you present will be converted. The DAC output connects to the
        input of the multiplexer and the input of the X Axis integrator.
        PORT A which feeds the DAC also connects to the AY-3-8192 so when
        you write to the sound chip make sure that either/both the BLANK
        and RAMP signals are not asserted, otherwise you may draw crap
        all over the CRT.


2) The MULTIPLEXER (Mixed Digital/Analog)

        The output of the DAC is connected to the input of the Multiplexer
        IC (one half, the other half is used for AtoD conversion of the
        joypad potentiometers). The Multiplexer takes the input signal
        and switches to any one of FOUR output lines, the input signal
        is only ever connected to one output line at any one time.

        The multiplexer has 3 control inputs. The first, the ENABLE signal
        comes from the 6522A SWITCH line from PORT B Bit0 (See the 6522A
        section on how to set/clear this bit). When this line is ACTIVE
        the input pin is connected to the selected output pin, just as
        if a mechanical switch were thrown, when NEGATED the input and
        output pins are completely isolated from each other.

        The other two inputs SEL0 and SEL1, again from PORT B of the 6522
        Bits 1 & 2 respectively. These bits are used to form a 2 bit number
        in the range 0-3, and when the multiplexer is active (see above)
        these inputs are used to decide which ouput pin is connected to
        the input pin. The Pin/Channel numbers for the Vector multiplexer
        are given below:

                0 - Y Axis integrator channel

                1 - X,Y Axis integrator offset

                2 - Z Axis (Vector Brightness) level

                3 - Connected to sound output line via divider network


3) X-Axis integrator, Y-Axis integrators (Analog)

        Before the input to each integrator is an analog switch, this
        switch is connected to the RAMP line from the 6522PIA PORT B
        Bit7. When the switch is closed (RAMP=0) the integrators will
        integrate the Value presented on the input, when RAMP is negated
        and the switch opened no integration action can occur and the
        integrators will hold their current value (see ZERO function).
        The outputs will follow the following form:


                     ^
                    |
               1    |
           -  ---   |  ( Vin - Voffset ) dT   + Constant
              CxR   |
                    |
                   v

        For the X,Y integrators R=10000 and C=0.01x10E-6

        When we fill the numbers in we get:


           Vout = - ((10000 x (Vin-Voffset) x Integration time) + Voutstart)


        Assuming that the full deflection voltages are +5V and -5V we can
        calculate the beam movement. This is always a relative movement
        based on the last position of the beam. If you want to be sure of
        where the beam is make sure you ZERO the integrators first then
        you can be sure the beam is at 0,0.


           IntInput  = (DAC value - 128) * (10/256)

           IntOffset = (DAC value - 128) * (10/256)

        The 10/256 comes from a 10 volt possible swing on the DAC in 256
        steps, therefore one step is 10/256 Volts. The -128 turns the DAC
        value into a plus/minus value.


           delta X = - ((10000 x (IntInput-IntOffset) x RAMPtime) + X)
            (or Y)

                 X = X + detla X

        Assuming the vextrex usable screen area is 8 Inches which converts
        to 20.3 cm. This is equal to 10 volts of swing.

        (Note 8 inches is a guess, I dont have a vectrex screen to measure
         so please correct me if I'm wrong, also these firgures dont take
         into accound any overdrive of the screen area, and will therefore
         be slightly incorrect, though by how much I wouldnt like to say)


             X pos = X (volts) * 2.03 (cm/volt)
              (or Y)

        This value is again referenced to the 0,0 point in the centre
        of the screen.

        The power supply to the integrator comes from the +5V and -5V
        analog power supply. No matter how long we integrate for we can
        never exceed the supply rails, if we integrate for too long then
        then integrator will saturate. Typicall the integration time, the
        length of the active RAMP pulse will be quite short, in the order
        of microseconds or milliseconds.

        To move over the full range of swing (10volts) it will take ??
        Assuming Voffset=0 and Voutstart=0 and no saturation.


                10 = - 10000 x -10 X Integration time

                Integration time = 100us = 0.1ms

        This is for drawing the largest possible vector, from one side
        of the screen to the other.


                Vout = -5V to +5V in both X and Y Axis


4) RAMP (Digital, Active Low)

    As mentioned above the RAMP signal controls the integrator integration
    time described in the previous section. This line is an active low
    signal and is connected to the 6522 PIA Port B Bit 7.


5) ZERO (Digital, Active Low)

    This line is connected to the 6522 CA2 line, see the 6522 section for
    info on how to set this line up. As with RAMP is is an active low
    signal. During any integration operation this line must be set to
    the inactive state (HIGH).

    When ACTIVE this line will cause the integrator output to be set to
    0V which will be the centre of the screen. This line should be
    ACTIVATED before any line drawing sequence to set the integrators to
    a known value. The integrator output value is held by a small capacitor
    and this will leak charge, basically the result is that over a period
    of time the when the integrator in not in RAMP mode its output will
    slowly fall to zero. So after drawing a sequence of vectors it is best
    to zero the output to give a solid reference.

6) Z-Axis Signal (Analog)

    This signal controls the Z Axis of the CRT, the brightness. It is
    set be setting the multiplexer to the Z-Axis setting and writing a
    value to the DAC. This signal is connected to a Sample and Hold
    circuit so you can switch the multiplexer away from this signal and
    it will hold it value.

    As with the integrators (See 3,7) the sample and hold will slowly
    drift towards zero, so every now and then in will need to be
    re-written. A good idea would be to write this value once for each
    object being drawn, or once per group of screen refresh if you are
    using a constant brightness, of course if your vectors are of
    differing brightness then you will need to set this value for each
    vector anyway.

7) BLANK (Digital, Active High)

    So that you dont need to change the brigness when positioning the
    CRT beam on the Screen you can use this line to temporarily BLANK
    off the Z-Axis signal, when NEGATED the Z-Axis signal will return
    to its old value.



Bringing it all together

The main basis if the vector drawing as weve seen is the X and Y integrators,
the Z Axis brightness is a passive system and easily understood. Just in
case the technical bit has lost you here is an analogy to explain the
integrator system.

We'll convert all of our electrical system to some household plumbing.
Voltages will convert to water pressure and current/charge to water
flow.

So our DAC is a TAP and the value we write to is the water pressure
behind the tap. An integrator can be thought of as a water tank. The
screen deflection is measured by the level of the water in the tank.

So when we set the DAC values we set the water pressure at the tank
inlet. The RAMP switch controls the ON/OFF of the tap. So the higher
the pressure (X,Y integrator values from the DAC) the faster the
water will flow into the tank and the faster the level will rise, ie
the water level is the vector position, we have two tanks X and Y.

So you can see we have two ways of regulating the water levels, the
water pressure and the amount of time we leave the tap on for.

Halfway down the side of each tank is a valve marked ZERO. We always
start with our tanks half full. And after we've poured our water in
we can open the ZERO valve to dump out excess water and bring ourselves
back to the zero point (the screen centre).

But our system has a twist, we can set the input taps to a negatve pressure
and suck water from the tank, and when we open the ZERO valve water will
flood in to fill us back up to the mid point. Our system also has a
few minor problems, our tanks have holes in them and slowly let the water
out back down to the middle level, and the pressure we set on the Tap
slowly fades away, so we must always ZERO and set the Tank pressure
before a flush/fill cycle.

Its in this manor that we can push the CRT beam around the screen to
create the vectors we require.




How to draw a Vector
~~~~~~~~~~~~~~~~~~~~

Maybe after reading the above you now have a pretty good idea about
how to draw vectors, or maybe you werent really interested and skipped
it, so here is the info on how to draw a vector.


    Step    1   Set the BLANK bit to 0, it should already be set to
                this to stop it dribbling crap on the screen when idle

            2   Set the ZERO bit to 0 to clear the integrators

            3   Set the RAMP bit to 1

            4   Set the ZERO bit back to 1

            5   Enable the Multiplexer and select Z-Axis

            6   Write your Vector Brightness to the DAC

            7   Setect the X,Y Axis integrator offset and write
                your value to the DAC, this can be used to scale
                the X,Y axis up/down.

     --->   8   Set the BLANK line according to wether this operation
    |           is going to be a DRAW or POSITION operation
    |
    |       9   Select the Y-Axis to the multiplexer and write your
    |           Y-Axis Vector Velocity value to the DAC.
    |
    |       10  Disable the Multiplexer
    |
    |loop   11  Write your X-Axis Vector Velocity to the DAC.
    |
    |       12  Set RAMP to 1
    |
    |   < Vector is now being drawn>
    |
     ---    13  Set RAMP to 0

        < Vector has finished >

            14  Set BLANK to 0 to stop any more info being drawn on the
                CRT no that weve finished.

The above can be run in a loop for each object or the whole screen, I dont
know how the EXEC ROM does it but I would run the 1-14 sequence once
for each object, ie the 8-13 loop for the components of the object. This
would ensure the repeatability of object positioning as each object is
always placed with reference to zero rather than the last object drawn.
If you dont do a zero its likely that errors will build up and your
objects may appear wobbly or jittery.

Parts 5&6 of the sequence can be omitted if you are only positioning the
vector ready for drawing.

Now comes the tricky bit, just how do we calculate the values for X and
Y velocity, X,Y integrator offset and how long do we make the RAMP
pulse.

The LENGTH of the RAMP pulse is critical if the screen is to appear
stable, you MUST disable the interrupts during the vector drawing cycle
as an interrupt occuring when RAMP is active would alter the length of
the RAMP pulse.

As I see it there are 3 possible ways to drive the system. All assuming
that X,Y integrator offset is constant, you can use is for zoom in/out
effects.


1) The most likely way the EXEC ROM does it (IMHO). We have a FIXED length
   of RAMP pulse for ALL vectors. Then with the 8 bit DAC values we
   have a 255 unit resolution on vectors in both the X and Y axis. This
   doesnt mean the screen resolution os 256x256, depending on the values
   used for RAMP time and XY integrator offset a 255 unit vector could
   be extremely small OR very large, its because everything is done
   relative to the last integrator position. I reckon this method involves
   the least calculation. You fix RAMP and then set the unit length with
   the XY integrator offset.

2) We have a look-up table of X,Y values depending on the direction that
   we want to move (you could calculate the values) and these are all
   scaled for a single fixed unit length vector. We then have a choice of
   either varying the RAMP length or XY integrator offset to procuce
   the length of vector we required, we just multiply the values of X and Y
   integrator settings for the fixed unit length by the length we require.

3) The most complicated way. We can vary all of the variables, but god
   only knows how we would calulate them, we would have four varibles.

Solutions 1 and 2 look the most promising as they restrict the number
of variables we have to calculate. Using a fixed value of RAMP would
seem the easiest thing so that we avoid any problems of CPU cycle counting
to get the required RAMP settings, we would need good control of the
RAMP time resolution, which is awkward, though not impossible in software
expecially when there is no hardware timer.

Without access to a Vectrex and some development tools to write some
test code I cannot test any of these THEORYs and work out conversions
from DAC values,times to Screen positions. As I dont know what the full
screen deflection voltages are, I would assume that the Max/Min integrator
values will corrspond to the Max/Min screen deflection values, or maybe
the Max/Min value is off screen, but by how much ??

WARNING: Dont go poking around the insides of the vector delecftion
circuitry. The logic board only contains low voltage circuitry but
the voltage chopper for the vector deflection circuit produce voltages of
around 5000Volts. YOU HAVE BEEN WARNED.

When I get time to Disassemble the EXEC ROM I can clear up once and for
all how the EXEC draws vectors.


