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.
' 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:
' 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
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
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:
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"
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
Quote from: Malban on September 21, 2016, 10:57:41 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:
LDD #(y and x coordinates combined into one word)
JSR Moveto_d
and a Lines sprite compiles to a Draw_VLp call:
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
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 :-)
Quote from: Malban on September 21, 2016, 12:05:08 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
Ok,
It is the "zeroing" - the attached screenshot is the result of the program below:
Inserting a:
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:
JSR Delay_3
(after anything BIOS related that finishes with a Reset0Ref)
;***************************************************************************
; 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
Thank you. I'll incorporate this into the next release of the firmware. (No, I don't know when that will be yet.)
- Bob
Last on the subject matter :-)!
New Vide zeroing emulation, takes into account, that integration WHILE zeroing is possible.
Regards
Malban