Re: [stella] my programs aren't good enough at doing nothing

Subject: Re: [stella] my programs aren't good enough at doing nothing
From: Andrew Towers <mariofrog@xxxxxxxxxxx>
Date: Tue, 27 Aug 2002 18:48:56 +1000

As I haven't been posting to the list much (at all actually), I thought this would be a good oportunity to make a fool of myself (as required to initiate all newbies).

So I've taken Kirk Israel's Thin Red Line and added a few comments to
try and explain the problems he's on about, and anything else that
came to mind at the time.

In the end I took a copy and rearranged it liberally with lots more
comments added in for good measure. This one gives me a nice clean red
line and no artifacts in Z26, and a single (erroneous I think) HMOVE
blank in StellaX. I don't have an NTSC TV here just at the moment so
I haven't tested this on a real live TV.

Only one thing is giving me grief; when I set TIM64T to 43, I didn't
get the exact timing I was expecting - it's actually out by around 64
cycles (give or take 5). Any explanation of this would be greeted with
profound thanks and adoration.

- Andrew.

-----------------------------------------------------------------------------

; thin red line by Kirk Israel
	
	processor 6502
	include vcs.h
	org $F000
Start
	SEI	
	CLD  	
	LDX #$FF	
	TXS	
	LDA #0		
ClearMem
	STA 0,X		
	DEX		
	BNE ClearMem	
	LDA #%11001000		; melon green
	STA COLUBK	
	LDA #33
	STA COLUP0
	
; Misc note: the VSYNC is turned on and off on cycles 12 and 11 respectively
; (this is for the second and subsequent frames; for the first frame the
; VSYNC will happen at a completely random time.) I'm not sure how safe
; this is or whether it matters, but this means the VSYNC will be a bit
; out of phase with the horizontal timing in the TV.

MainLoop
	LDA  #2			;+2
	STA  VSYNC		;+3 *12*
	STA  WSYNC		;-- end of first VSYNC line
	STA  WSYNC 		;-- end of second VSYNC line
	STA  WSYNC		;-- end of third VSYNC line
	
; Setting the timer to 44, 45 or 46 reduces the half-line relic because
; it is shifting the "unknown positions" (commented below) to the right
; by 64 cycles each time. This visually moves the start-of-line left
; by 12 cycles (76-64=12) or 36 pixels and moves the start of screen
; down one line, which also breaks the 262-line VSYNC timing.

	LDA  #43		;+2
	STA  TIM64T		;+4
	LDA #0			;+2
	STA  VSYNC 		;+3 *11*

WaitForVblankEnd
	LDA INTIM
	BNE WaitForVblankEnd
	LDY #191

; The following "unknown positions" cause the half-line of background colour
; and also the extra dot lagging behind on the second half of the top line
; (because the missile is enabled half way along the line above the HMOVE.)
; Running Z26 in trace mode shows that the VBLANK is done on cycle 40,
; part-way along a scanline.

	STA VBLANK		;+3 *?* unknown position on line
	LDA #$F0		;+2
	STA HMM0		;+3 *?* also unknown position

	STA WSYNC		;-- start first fully-visible line
	STA HMOVE		;-- there will be a HMOVE blank on this line
ScanLoop
	STA WSYNC		;--
	LDA #2
	STA ENAM0
	DEY
	BNE ScanLoop

	LDA #2
	STA WSYNC  		;--
	STA VBLANK		;+3 *3*
	LDX #30
OverScanWait
	STA WSYNC		;-- start of first VSYNC line on exit
	DEX			;+2
	BNE OverScanWait	;+2/3
	JMP  MainLoop		;+3

	org $FFFC
	.word Start
	.word Start

-----------------------------------------------------------------------------

; thin red line by Kirk Israel
; with timing tweaks by Andrew Towers

	processor 6502
	include vcs.h
	org $F000
Start
	SEI
	CLD
	LDX #$FF
	TXS
	LDA #0	
ClearMem
	STA 0,X
	DEX
	BNE ClearMem
	LDA #%11001000		; melon green
	STA COLUBK
	LDA #33
	STA COLUP0

; The VSYNC is changed on the 3rd cycle every time for the first and
; every subsequent frame, and occupies lines 1-3 (starting from line 1
; as does Z26 so I don't confuse myself or someone like me).

; In a Z26 trace, the STA VSYNC shows up as line 263 for cycles 0-2,
; then the line becomes line 1 starting on cycle 3. This looks odd but
; it makes sense to me if we need a total of 262 -whole- lines.

MainLoop
	LDA  #2			;+2
	STA  WSYNC		;-- wait for start of first VSYNC line
	STA  VSYNC		;+3 *3* start of line 1
	STA  WSYNC		;-- end of first VSYNC line
	STA  WSYNC 		;-- end of second VSYNC line
	LDA  #0			;+2
	STA  WSYNC		;-- end of third VSYNC line
	STA  VSYNC 		;+3 *3* start of line 4

; Set up the timer. We need to wait for 37 whole lines minus a bit, to
; make sure we drop out of WaitForVblankEnd before the end of the last
; VBLANK line. Since we're not scraping for processing time yet, we
; can just make sure we're waiting -more than- 36 lines (hence rounding
; down 37*76/64=43.94 to 43, giving 36.21 lines.)

; Now I can't get this to work properly in a Z26 trace. It always drops
; out of WaitForVblankEnd in the middle of line 39 (cycle 43) whereas
; I would expect it to be cycle 25-30 (9 + 0.21 * 76) on line 40.

; The only explanations I can think of are (a) I'm missing something
; (b) I'm going senile (c) The RIOT (or the Z26 emulation) doesn't
; reset it's div-by-64 counter when TIM64T is written. This would
; allow an end time anywhere between cycle 37 on line 39 and cycle
; 25 on line 40.

; In any case a count of 44 gives me the results I'm looking for,
; exiting the loop 63 cycles later on cycle 30 at line 40.
; Anyone have any ideas why my TIM64T count is out by one?

	LDA  #44		;+2 timer for 44*64 cycles
	STA  TIM64T		;+4 ... starting on cycle *9* line 4

; Use the VBLANK time to do setup for the next frame,
; such as enabling the missile and moving it into position.
; Note that nothing will be seen while VBLANK is on, so this
; won't produce any HMOVE lines or stray missiles.

	LDA #2
	STA ENAM0		; enable missile (not visible yet)

	LDA #$F0
	STA HMM0		; set up the missile movement
	
	STA WSYNC		;-- wait for start of any line
	STA HMOVE		; do the HMOVE now when no-one can see it

; Wait for the timer to end. Note that we have a 64-cycle window of
; opportunity to spot the zero-count, which is plenty for a 5-cycle
; loop.

WaitForVblankEnd
	LDA INTIM
	BNE WaitForVblankEnd

; We will drop out of the timer loop somewhere in the middle of the
; last line of VBLANK (line 40), so we'll have to wait for the end
; of that line before turning VBLANK off.

	LDA #0			;+2
	STA WSYNC		;-- wait for start of first visible line
	STA VBLANK		;+3

; Now we're 3 cycles into line 41, the first visible scanline.

	LDY #191
ScanLoop
	STA WSYNC		;-- count 191 more visible lines
	DEY
	BNE ScanLoop

; Now wait for the end of the last visible line (232), start of the
; first line of overscan (233), and immediately turn on VBLANK.

	LDA #2
	STA WSYNC  		;-- wait for end of visible line 192,
	STA VBLANK		;+3 *3* start of first overscan line

; There are 29 start-of-lines left in the overscan, then we can jump
; to the top which will finish the 30th line.

	LDX #29
OverScanWait
	STA WSYNC		;-- wait for the start of 29 more lines
	DEX			;+2
	BNE OverScanWait	;+2/3

; Jump back to the start, which will wait for the end of the last
; overscan line (262), start of the first VSYNC line (1) before
; doing anything.

JMP MainLoop ;+3

	org $FFFC
	.word Start
	.word Start


---------------------------------------------------------------------------------------------- Archives (includes files) at http://www.biglist.com/lists/stella/archives/ Unsub & more at http://www.biglist.com/lists/stella/


Current Thread