Author Topic: Simplest program - question  (Read 371 times)

Malban

  • Newbie
  • *
  • Posts: 9
    • View Profile
Simplest program - question
« on: September 21, 2016, 05:26:52 AM »
Hi,

I have only recently begun fiddling with Vectrex32 and the most simple program I can imagine does not realy behave the way I expect it.

Code: [Select]
' test

textSize = {40, 5}
instructions = {{-50, 90, "DISPLAY VECTORLIST"}}
VectorList={_
        {MoveTo, +$20, -$40}, _
        {DrawTo, +$20, +$00}, _
        {DrawTo, +$00, +$40}, _
        {DrawTo, -$20, +$00}, _
        {DrawTo, -$20, -$40}, _
        {DrawTo, +$20, +$00}, _
        {DrawTo, -$20, +$00}, _
        {DrawTo, +$20, -$40}}

call IntensitySprite(50)

call TextSizeSprite(textSize)
call TextListSprite(instructions)

// NOT OK
call ScaleSprite(25)
vListSprite=LinesSprite(VectorList)

while true
    controls = WaitForFrame(JoystickNone, JoystickNone, JoystickNone)
endwhile
The display I get (see first attachment image)


A very simple solution is to display the vectorlist BEFOR the text:
Code: [Select]
' test

textSize = {40, 5}
instructions = {{-50, 90, "DISPLAY VECTORLIST"}}
VectorList={_
        {MoveTo, +$20, -$40}, _
        {DrawTo, +$20, +$00}, _
        {DrawTo, +$00, +$40}, _
        {DrawTo, -$20, +$00}, _
        {DrawTo, -$20, -$40}, _
        {DrawTo, +$20, +$00}, _
        {DrawTo, -$20, +$00}, _
        {DrawTo, +$20, -$40}}

call IntensitySprite(50)

// OK
call ScaleSprite(25)
vListSprite=LinesSprite(VectorList)

call TextSizeSprite(textSize)
call TextListSprite(instructions)


while true
    controls = WaitForFrame(JoystickNone, JoystickNone, JoystickNone)
endwhile

This works fine... (see second attachment image).

But why is that?
The behaviour is not what I expected and I haven't found any clue about it either.

Malban

Vectrex32

  • Administrator
  • Full Member
  • *****
  • Posts: 100
    • View Profile
Re: Simplest program - question
« Reply #1 on: September 21, 2016, 08:48:09 AM »
Hi Malban,

I found that by adding this line before "call ScaleSprite(25)", it fixes the problem:
   call MoveSprite(1, 1)

The Vectrex has a problem drawing things right after resetting the pen to the origin - things get messed up the way you're seeing it. Chris Salomon mentions it in his tutorial; his solution is to introduce a delay but he mentions that if you're moving the pen anywhere, that will add a sufficient delay and effectively solve the problem.

The Vectrex BIOS resets the pen after drawing text. So if you draw your sprite immediately afterwards, it will get messed up. Adding the MoveSprite introduces sufficient delay.

It occurs to me that I should implement a "Delay" pseudo-sprite to more cleanly address this problem.

- Bob
 

Malban

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Simplest program - question
« Reply #2 on: September 21, 2016, 10:57:41 AM »
Hm.

Originally I thought it might be like you said, I DID in fact test inserting a  "call MoveSprite(0,0)" which did NOT help.

I tried your  "call MoveSprite(1,1)" and this does work. Do you check for "0,0" and optimize that call out?
Also: I remember having written about "a delay" (Malban == Chris Salomon :-)) But I don't think that is the "fault".

If only that would be the case than I guess adding some other sort of delay, like:

Code: [Select]
call IntensitySprite(50)
call IntensitySprite(51)
call IntensitySprite(52)
call IntensitySprite(53)

Would also do the trick - which it doesn't (unless some under the hood optimization is going on).
The reasoning behind the delay after the "Reset0Ref" is, that the actual enabling of the ~Zero line in the BIOS function is done without a wait loop.
The "worst" thing that can happen is that you position/draw the next object to early and the zero point was not reached yet.
So only some kind of offsetting would happen - not a complete wrong "picture".

Another thing that can be troublesome after WaitRecal/Reset0Ref is that the VIA_CNTL is set to "wrong" values.
The above functions set the register to $CC
(%110x110x = $cc means ZERO enabled, and BLANK enabled)

With that value no drawing of any kind is possible.

To be able to output anything to vectrex again you must set the Via register to: $CE again.
(%110x111x = $ce means ZERO disabled, and BLANK enabled)

One way to "enable" drawing again is to either to do it "manually"
Code: [Select]
      LDA     #$CE            ;Blank low, zero high?
      STA     <VIA_cntl

Or to do a "Moveto_d" (e.g. with 0,0 as positioning) as this function sets the VIA_cntl register to exactly that value.

But since (see screenshots) something is indeed output to vertex (and the lines have lengths other than zero) - this can't be the fault either.

I am at a loss why the display list reacts as it does, and why a "call MoveSprite(1, 1)" really helps.

Perhaps we can somehow have a peek at the actually generated assembler display list code?

Regards
Malban
« Last Edit: September 21, 2016, 11:00:22 AM by Malban »

Vectrex32

  • Administrator
  • Full Member
  • *****
  • Posts: 100
    • View Profile
Re: Simplest program - question
« Reply #3 on: September 21, 2016, 11:30:51 AM »
(Malban == Chris Salomon :-))

Oh... uh... hi Chris. BTW, thank you so much for the tutorial you wrote. None of this would've been possible without it.

Yes, a MoveSprite(0, 0) gets optimized out. Multiple intensity sprites do not get optimized out.

So if I want to get get rid of the Move sprite after the reset to 0,0, can I have a delay and then write $CE to VIA_Cntl?

I guess I don't understand why those lines don't draw right either. I've seen that behavior since I first started working on the SmartCart, so I assumed it was what you were talking about in your tutorial.

A Move sprite compiles to a Moveto_d:

Code: [Select]
          LDD #(y and x coordinates combined into one word)
          JSR Moveto_d

and a Lines sprite compiles to a Draw_VLp call:

Code: [Select]
          LEAX 3,PC           ; Loads the address of LineData
          LBRA AfterData   ; Skips over the data
LineData:
          (pattern, rely, relx data goes here)

AfterData:
          JSR Draw_VLp


If there are no sprites between the Move and the Lines, there will be no 6809 code between the snippets above.

- Bob

Malban

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Simplest program - question
« Reply #4 on: September 21, 2016, 12:05:08 PM »
Hi
I will try to write a "direct" assembler program and recreate the situation.
Is there anything "special" done to the coordinates? I mean - you must translate from x,y to y,x and from absolut to relative...

Ill report any findings...  :o.

Malban

PS.
A "macro" from the screenshot, is this the result of zero being active an drawn nonetheless?

Time to experiment :-)







Vectrex32

  • Administrator
  • Full Member
  • *****
  • Posts: 100
    • View Profile
Re: Simplest program - question
« Reply #5 on: September 21, 2016, 12:10:28 PM »
Is there anything "special" done to the coordinates? I mean - you must translate from x,y to y,x and from absolut to relative...

Yes, I do those conversions, but they're done the same way whether the previous sprite was a Move or not. One sprite doesn't affect the other.

- Bob

Malban

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Simplest program - question
« Reply #6 on: September 21, 2016, 12:30:23 PM »
Ok,

It is the "zeroing" - the attached screenshot is the result of the program below:

Inserting a:
Code: [Select]
LDA     #$CE            ;Blank enabled, zero disabled
STA     <VIA_cntl

gives correct results.

The delay is most of the time not necessary only in extreme fast/direct situations. If you want to be on the save side you can additionally insert a:
Code: [Select]
JSR Delay_3 (after anything BIOS related that finishes with a Reset0Ref)

Code: [Select]
;***************************************************************************
; 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       "NEW PROG", $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
                    LDU      #hello_world_string  ; address of string
                    LDA      #$10                 ; Text position relative Y
                    LDB      #-$50                ; Text position relative X
                    JSR      Print_Str_d          ; Vectrex BIOS print routine

                    LDA      #$40                 ; scalefactor
                    STA      VIA_t1_cnt_lo
; HERE HERE HERE
                    LDX      #vData               ; address of string
                    JSR      Draw_VL_mode         ; Vectrex BIOS print routine


                    BRA      main                 ; and repeat forever

;***************************************************************************
; DATA SECTION
;***************************************************************************
hello_world_string:
                    DB       "HELLO WORLD"        ; only capital letters
                    DB       $80                  ; $80 is end of string
;***************************************************************************

vData = VectorList
VectorList:
 DB $00, -$40, +$20 ; mode, y, x
 DB $02, +$40, +$00 ; mode, y, x
 DB $02, +$40, -$20 ; mode, y, x
 DB $02, -$40, -$20 ; mode, y, x
 DB $02, -$40, +$00 ; mode, y, x
 DB $02, +$40, +$40 ; mode, y, x
 DB $02, +$00, -$40 ; mode, y, x
 DB $02, -$40, +$40 ; mode, y, x
 DB $01 ; endmarker (1)

Ok, now I have to enhance Vide emulation again - to show exactly that behavior.

 :-\

Malban

Vectrex32

  • Administrator
  • Full Member
  • *****
  • Posts: 100
    • View Profile
Re: Simplest program - question
« Reply #7 on: September 21, 2016, 12:43:58 PM »
Thank you. I'll incorporate this into the next release of the firmware. (No, I don't know when that will be yet.)

- Bob

Malban

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Simplest program - question
« Reply #8 on: September 21, 2016, 02:53:25 PM »
Last on the subject matter :-)!

New Vide zeroing emulation, takes into account, that integration WHILE zeroing is possible.

Regards
Malban