Prof. Dr. rer. nat. Peer Johannsen

Weird Science - Tales from the Vectrex Academy Lab

Vectrex Project Title

  • Wait_Recal() and Deflection Protection

Project Status

  • Ongoing research


  • Digital Archeology - An investigation of the Wait_Recal() BIOS routine
  • While analyzing the source code of the Test Rev. 4 cartridge and especially the Deflection Protect test, I once again got side-tracked and did a closer investigation of the "wait" and the "recalibration" mechanisms of the BIOS.
  • Here is a summary of some interesting, yet probably utterly useless findings...

An analysis of the Wait_Recal() BIOS routine

  • These findings are mostly deductions based on code analysis and on what could be seen in experiments. Some of them are based on speculations, and I could confirm only a few things by looking at the board schematics, as I am not an analog hardware expert.
  • The Wait_Recal() routine essentially does a "wait" for timer 2 to expire in order to synchronize the framerate to 50Hz (or rather to the value stored in Vec_Rfrsh), and also a "recalibration" part, calling the "Recalibrate" BIOS routine.
  • My current theory is that "Recalibrate" is actually not about recalibration, but only about preventing the hardware Deflection Protection mechanism to activate. I also do think that in most applications calling Recalibrate is actually not necessary (and a waste of CPU cycles).
  • As best as I understand it, the hardware deflection protection mechanism kicks in, as soon as the deflection of the Y-axis coil goes to zero. In that case, the effective brightness of the electron beam is immediately reduced. If, for example, the ZERO signal is kept active for 20/50 seconds, the effective brightness goes down to zero and nothing can be seen on the screen. For shorter periods, the effect is just a dimmed brightness. I have verified this by lots of experiments, in which I used my own version of Wait_Recal() which does not interfere with the ZERO signal (which is a bit tricky to achieve).
  • If the ZERO signal stays active (or rather if there is no deflection on the Y-axis) for longer than 20/50 seconds, then the deflection of the electron beam is disabled, and the screen stays blank. In order to wake up from this state, a certain minimum deflection for a certain minimum time is required. Only then the deflection (and the brightness) are activated again, and things will appear normally on the screen again. Experiments vaguely suggest that a deflection of (127,0) for 32 cycles is enough.
  • The BIOS Recalibrate() essentially does two extreme moves with coordinates (127,127) and (-128,128) at scale factor 255, thus at regular intervals preventing the deflection protection from activating. So Recalibrate) seems to be not about recalibration, but only to be about keeping the display alive, in case that in between the program does not cause enough reflection of the electron beam.
  • This seems to be normal deflection protection mechanism used in TV CRTs. If the scan line generating mechanism of a TV (causing the high frequency X-deflections and the slower 50Hz or 60Hz Y-deflections to create the raster lines) fails, then the electron beam keeps shooting at the center of the screen, potentially burning a spot into the phosphor layer and damaging the screen. This is prevented by the above described mechanism.
  • On the Vectrex, we do not have scan lines. But the hardware protection mechanism is still there. So, if the electron beam is kept at the center of the screen for too long, the mechanism activates (independently of Z-axis integrator value).
  • If your program does "enough" beam movements in one frame (enough in the sense of enough distance and enough duration), then this is no problem at all, and the Recalibrate() is not necessary and just wasting cycles. In most of the normal applications this should be the case. Only if your program draws things merely at the center of the screen for many frames in a row, then this could cause a problem.
  • As said above, these deductions are based on experiments. Here are additional references to support this theory:
  • The original GCE documentation names "Recalibrate" as "DEFLOK", which is short for DEFLection OK. The BIOS source code says in the comment section "CALL TO KEEP POWER ON; SUPER LONG SATURATED KEEP ALIVE PULSE". The Mine Storm source code comment for DEFLOK says "OVER-COME SCAN COLLAPSE CIRCUITRY".
  • The GCE Programmer's Manual Part 2, page 40, says "DEFLOK’ is performed by calling FRWAIT. However, it has been necessary with some games to add additional DEFLOKs to prevent long-term screen collapse." Would be interesting to know which of the original games do more than just one call of DEFLOK in a single frame. Only evidence I found so far is the Mine Storm source code, which first calls FRWAIT and then DEFLOK. Since FRWAIT internally also calls DEFLOK, it is effectively called twice in a row. I still have to check if this is also the case in the Mine Storm binary.
  • Also note the schematics on page 31, which show a signal called DEFL_ENABLE and a box called "DEFL DETECT". In the schematics, this box is fed with the deflection value of the X-Axis, which I think is a mistake. According to my experiments, the deflection protection only cares about the Y-axis.
  • Some thoughts on programming methodology. Since it is potentially dangerous to keep the ZERO signal active for too long, it might not be a good idea to have a Reset0Ref() as the last function call before calling Wait_Recal(). Wait_Recal() first does the "wait", and then the "recal". So ZERO would be active during the complete waiting.
  • Same with drawing objects. I noticed that many programmers draw their objects like this: "Move_to(); Draw(); Reset0Ref(); logic_computations();", in order to assure that ZERO is on long enough to actually reach the center of the screen. However, this will potentially leave ZERO active for quite a long time. If you want to get rid of the recalibration moves, then you should take care of this. The reversed style, "Reset0Ref(); Move_to(); Draw(); logic_computations();" in that sense is better, as the Move_to() disables ZERO. However, you have to assure that ZERO is not disabled too early.
  • These findings are mostly deductions based on code analysis and on what could be seen in experiments. Some of them are based on speculations, and I could confirm only a few things by looking at the board schematics, as I am not an analog hardware expert.
  • To be continued. Comments are welcome!

Additions and Comments from Malban:

  • In optimized programs I still suggest the order: "Move_to(); Draw(); Reset0Ref(); logic_computations();". I have NEVER in my time experienced a screen collapse - and from what I understand - it would take  about 20 Vectrex rounds of zeroing in order to trigger that. The above order has "proven" to be good for clean zeroing.
  • Regarding Recalibrate(): In my experience (not electronically assured, but "feeled") - if you draw (many) things (in a row), the integrators "keep" some charge from the last positions they stayed in
    (regardless of how long you zero). Doing a recalibrate (moving to extrem positions) ensures that the integrators are in a defined state (whether that is exactly zero or not is of no concern, the important thing here is a defined state). Vide emulates this under the name "Integrator retain".


  • Peer Johannsen

Latest modification on 01/14/2023, 16:00
  • Page created