6th of February 2018 – VPatrol ingenuity part III

If you played VPatrol – you know what that is.

I personally think it represents a glider taken from a TV series called “Space: 1999” (German: “Mondbasis Alpha 1”).
That glider is part of the calibration routine within VPatrol.

You might say “so what”?

I tell you what – that is one single vectorlist consisting of over 60 vectors (and moves). There is no synchronizing done – no return to zero or anything else. That glider is drawn in one go!

Do you notice any drift?

If you did your calibration right – you don’t! That is the point! Usually if you draw more than say 10-15 vectors in one go – you will see all kinds of drift madness. I will not go into the calibration again – this time I’d like to take a look at the drawing routines themselves.

The routines Kristof uses I believe he calls “SmartList” for now I will keep that name. The routines themselves are not sooo much different than the ones from Thomas – and my Release routines might be also viewed as distant relatives. Nonetheless I never really investigated Thomas routines to closely and on this blog I never mentioned the object handling in Release – so for now I will present you the SmartList (or partials anyway).

Since I do not have the original sources – I must use my own naming conventions – please bear with me…

Following is the “main” section of a program that does the calibration (which is neccessary) and displays the glider:

Basically the first 9 lines ask the joystick for left/right and adjust the calibration value. Than there is the WaitRecal to ensure 50Hz, a call to our “calibrationZero” which goes to zero and sets DAC offset value. Than a “bad” slow MoveTo_d so the image of the glider is centered.

Than the glider is displayed. The address of the vectorlist loaded to register U and the “drawSmart” routine is called (which only does a pulu d,pc – Ha! This DOES look like Release after all 🙂 ).

Now the fun part!

What you see is a list of register A, B values and a “subroutine” call. To keep the list in “db” values I used in the above representation hi(), lo(). It might have been better to do something like:

 db 10,20; y, x value
 dw SM_startDraw_d

The data/list representation is “ultra” flexible. Basically its a string of subroutines which are always called with two parameters. Each subroutine is “closed” with another PULU a,b,pc – and automatically the values are loaded and the next subroutine is called – for the cost of mere 9 cycles.

E.g. the first subroutine “SM_setScale” is called with register A = 0, and register B = SPRITE_SCALE. The complete subroutine looks like:

SM_setScale: 
 stb <VIA_t1_cnt_lo 
 pulu a,b,pc

Thats all. But you could do more – … it could be an init routine of sorts, it could set the intensity or or or…

The subroutines Kristof wrote are the “smartest” things of this collection of routines:

This “moves” to the next location (y,x position given in before pulled a,b). The “clever” part here is, that the shift register is NOT changed. This

a) saves cycles
b) the subroutine can be used for a “continued” move or a “continued” draw.

The above one “starts” a move, it is ensured that Blank is 0!
The obvious counterpart is “SM_startDraw_d”.

But there is more “cleverness”:

Here you see reference to “SM_continue_newY_eq_oldX” that routine “knows” that the new y value is the same as the old x value – which means that DAC need not be set again, only the MUX (saving precious cycles).

Also “SM_continue_d_double”:

If two consecutive moves/draws are exactly the same – you can call a “double” function – which in general only enables ramp a second time (thru timer 1).

Notice the “bra” above seems a bit “stupid” – but there are timing issues. Timer1 must expire before setting it again, otherwise the full vector is not drawn – so if you encounter some “meaningless” code (like brn, or tfr a,a …) – that is usually timing related!

… and so on…
To generate “SmartLists” I guess Kristof has written a special program that disects vectorlists and examines them closely. Might do that in Vide some day too! 🙂

 

Timing

All “SmartList” functions I encountered seem to work “out of the box” up to a scale of 9 (perhaps 10). Above that scale the routines have timing issues.

This has todo with above mentioned Timer1 which must be allowed to expire before doing anything new. Within all SmartList functions there is not one Wait loop or interrupt flag interrogating – the timer is ALWAYS expired before the next relevant changes are made! (Which again reminds me of my own “fast draw” routines – I usually also do not have idle loops).

If you happen to use Kristof functions and want to use larger scales than “9” you have to change the code.

The changes are actually quite simple – after each “clr <VIA_t1_cnt_hi” you can place a macro call to something like:

SPRITE_SCALE = $20 

ADD_NOPS macro 
 if SPRITE_SCALE>9 
   nop (SPRITE_SCALE-9)/2 
 endif 
 endm

That macro “inserts” the right amount of nop (no operation – 2 cycles idle…) into the routines. The above image I took from the vectrex is the glider drawn with a scale of $20.

Calibration still works – even with that “high” scale!

Speed

Well, you might think – why bother this seems really complicated…

a) No – it isn’t. Perhaps you have to resolve some knots in your brain and think a bit differently (perhaps a bit OO) – but this drawing is really efficient!

b) Speed – the routines if all “cleverness” is used are damn fast, drawing the glider with scale 9:

Draw_VL_Mode: 7803 cycles

Draw_VLp: 4825 cycles

drawSmart: 2122 cycles

 

Malban

Tagged on: ,

13 thoughts on “6th of February 2018 – VPatrol ingenuity part III

      1. gauze

        ok I sat down with this and went over it over a few sections, the stack operators on ROM and using PC for “function” calls is clever. not sure why you used DB instead of DW for that part from the start of your example, I had to look up hi() lo() in the as09 man page once I realized it wasn’t some kind of macro!

        request:
        Do you have a full source code example of “GLIDER CALIB” I could peep at?

        1. Malban Post author

          Yeah, sometimes I am thinking around the corner :-). The hi/lo thingy was one of those.
          It would have been better to do a dw.

          PS email on its way…

  1. gauze

    can I request a part IV? The FONTS look just so gorgeous, smoother than other “raster draw” routines I’ve seen (imho!) is there any kind of magic here or did he just choose his style of fonts well?

    1. Malban Post author

      I might look into that – at some future time :-).
      I looked a little bit at his print routines – but rather how the texts are gathered than how the font (raster) printing was done.

      His routines are “tricky” in the way that I think no word (or very few) are more than once in memory. All sentences (and titles) are
      sorted together during runtime – very memory efficient.

      Right now I am very much “Vectorblading” – and I probably won’t to other Vectrex stuff in parallel…

      Malban

  2. Phillip Eaton

    I read through this when you posted it and didn’t really understand it (and didn’t have a use case for it anyway). Now I do have a use case and on reading it again, I do understand it! It’s a nice technique, kind of like a vector drawing version of stack-blasting. Thanks for posting the information, now I will look at SmartLists in VIDE.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.