Re: [stella] Syncing without WSYNC

Subject: Re: [stella] Syncing without WSYNC
From: "B. Watson" <atari@xxxxxxxxxxxxxx>
Date: Fri, 31 Aug 2001 09:54:24 -0400 (EDT)
On Fri, 31 Aug 2001, Manuel Polik wrote:

> "B. Watson" schrieb:
> 
> > But... if you're modifying GRP0/1 several times in one scanline, the second
> > line will display whatever the last value was all 3 times it's being displayed..
> > I could store zeros in both player registers, but then my 6 digit score would
> > come out zebra-striped...
> 
> Doing a 6-char routine with closed spacing is a *trick* not something
> that can be just *programmed*
> Either you know how it works or not. 
> You'll never get it going properly without deeper knowledge about the
> exact inner workings of VDEL & GRPX writes.
> 
> (Just a side-note to save you time, but keep on trying if you feel like
> doing it the impossible way... :-))
> 
> Greetings,
> 	Manuel
> 

Oh, I don't mind attempting the impossible... anyway, I wasn't trying to
do it with close spacing, I'm using wide spacing (NUSIZ value 3), and I did
get it to work that way. It's still ugly, but no uglier than using PF*
registers to draw text. And I learned a lot about how the CPU/TIA timing
works, that will be good to know in the future.

When I do decide to mess with a real (close-spaced) 6-digit score, I'll
cut & paste some code from the biglist archives, and play with it until I
understand how it works... by breaking it and understanding how it broke,
if nothing else.. One of the golden rules of programming for me has always
been to know exactly what's going on and how it works, at all times.. Which
is probably an obsolete attitude if you're coding in C++ or Java (you treat
objects like a `black box'), but it's a habit I can't break..

Anyway, what I've got, I'm attaching to this message, for a laugh.

Brian

---

If a trainstation is the place where trains stop, what is a workstation?


------------------------------------------------------------------------------
; score.asm

; by B. Watson <atari@xxxxxxxxxxxxxx>

; Draws a 6-character, wide-spaced, 6-digit score.

; Tested on z26 v1.46 on a windows machine
; Tested on xstella 1.1 on a linux machine
; *Not* tested on a real Atari (yet)

 processor 6502
 include "vcs.h"

 seg.u data

 org $80

framectr ds 1
digit0 ds 6
digit1 ds 6
digit2 ds 6
digit3 ds 6
digit4 ds 6
digit5 ds 6
tmp0 ds 1
tmp1 ds 1
tmp2 ds 1
tmp3 ds 1
tmp4 ds 1

 seg code

 org $F000

 sei
 cld
 ldx #$ff
 txs
 lda #0
iloop
 sta 0,x
 bne iloop

 ldx #5
rz_loop
 lda dec0,x
 sta digit0,x
 lda dec1,x
 sta digit1,x
 lda dec2,x
 sta digit2,x
 lda dec3,x
 sta digit3,x
 lda dec4,x
 sta digit4,x
 lda dec5,x
 sta digit5,x
 dex
 bpl rz_loop

main_loop
 lda #2
 sta VSYNC ; start blanking
 sta WSYNC
 sta WSYNC
 lda #44
 sta TIM64T ; go ahead & set timer
 lda #0
 sta WSYNC
 sta VSYNC ; 3 WSYNC's, then turn off VSYNC

; here is where I'd calculate the score, if I were in a real game
;calc_score
; lda scorelo

; position players for top 10 scanlines (the score). Fixed positions.
 inc framectr ; rotate color every other frame
 lda framectr
 lsr
 sta COLUPF

 lda #3
 sta NUSIZ0
 sta NUSIZ1


 lda #10
 sta COLUP0
 sta COLUP1

 sta WSYNC
 repeat 17
 nop
 repend
 sta RESP0 ; p0 at ((17*2)+3-22)*3 cycles = 45 pixels (37 cycles)
 repeat 6
 nop
 repend
 sta RESP1 ; p1 at ((17*2)+3+(6*2)+3-22)*3 pixels = 90
 lda #$C0 ; +4 pixels to the right = 92 (53 cycles)
 sta HMP1
 sta WSYNC
 sta HMOVE
 sta WSYNC
 sta HMCLR

wait_timer
 lda INTIM
 bne wait_timer ; busy-wait for timer to expire
 sta WSYNC

kernel

; ldy #192
;next
; sta WSYNC
;; each player is 8 pixels wide. each CPU cycle is 3 pixels (!), therefore each player is 2.66 CPU cycles wide!
; lda #$ff ; 3
; sta GRP0 ; 3
; sta RESP0 ; 3
; tya ; 2
; adc framectr ; 3
; sta COLUBK ; 3 (so far 17)
; nop ; 2
; nop ; 2
; nop ; 2
; lda #$AA
; sta GRP0 
; dey
; bne next
 
; start off with 5 scanlines of pure hell :)
 ldy #5
 tsx ; we're going to use S as a register, better hang on to it.
do_score
 sta WSYNC
 lda digit0,y ; 4
 sta GRP0 ; +3 = 7
 lda digit3,y ; +4 = 11
 sta GRP1 ; +3 = 14
 repeat 5 ; +10 = 24
 nop
 repend
 lda digit1,y ; +4 = 28
 ldx digit2,y ; +4 = 32
 nop ; +2 = 34
 nop ; +2 = 36
 nop ; +2 = 38
 sta GRP0 ; +3 = 41
 nop ; +2 = 43
 nop ; +2 = 45
 stx $2000+GRP0 ; +4 = 49
 nop ; +2 = 51
 lda digit4,y ; +4 = 55
 sta GRP1 ; +3 = 58
 lda digit5,y ; +4 = 62
 sta GRP1 ; +3 = 65
 ; #define LAME_CUT_AND_PASTE
 sta WSYNC
 lda digit0,y ; 4
 sta GRP0 ; +3 = 7
 lda digit3,y ; +4 = 11
 sta GRP1 ; +3 = 14
 repeat 5 ; +10 = 24
 nop
 repend
 lda digit1,y ; +4 = 28
 ldx digit2,y ; +4 = 32
 nop ; +2 = 34
 nop ; +2 = 36
 nop ; +2 = 38
 sta GRP0 ; +3 = 41
 nop ; +2 = 43
 nop ; +2 = 45
 stx $2000+GRP0 ; +4 = 49
 nop ; +2 = 51
 lda digit4,y ; +4 = 55
 sta GRP1 ; +3 = 58
 lda digit5,y ; +4 = 62
 sta GRP1 ; +3 = 65
 ; #undef LAME_CUT_AND_PASTE :)
 dey ; +2 = 67
 bpl do_score ; +3 = 70 (plus the STA WSYNC again is 73)

; this actually works, for drawing constant data!
;do_score
; sta WSYNC
; lda #255 ; 3
; sta GRP0 ; 3
; sta GRP1 ; 3
; ; so far 9
; repeat 7
; nop
; repend
; ; so far 9+14 = 23
; lda #$AA ; +3 = 26
; nop ; 28
; nop ; 30
; nop ; 32
; nop ; 34
; nop ; 36
; nop ; 38
; nop ; 40
; sta $2000+GRP0 ; 44, now!
; lda #%11100111 ; 47
; sta GRP0 ; 50 ; that's 3 GRP0's
; nop ; 52
; nop ; 54
; nop ; 56
; nop ; 58
; sta GRP1 ; 61 
; lda #$AA ; 64
; sta GRP1 ; 67
; dey ; 69
; bpl do_score ; 72 (and the STA WSYNC above makes 75. *whew*)

 sta WSYNC

 lda #0
 sta GRP0
 sta GRP1

 ldy #180
blank_pf
 sta WSYNC
 dey
 bne blank_pf

end_kernel

 lda #37
 sta TIM64T
overscan
finish_overscan
 lda INTIM
 bne finish_overscan

 jmp main_loop

 org $F800
decfont
dec0
; byte %00000010
; byte %00000101
; byte %00000101
; byte %00000101
; byte %00000010
 byte %00011100
 byte %00100010
 byte %00100010
 byte %00100010
 byte %00011100
 byte %00000000
 byte %00000000
 byte %00000000
dec1
; byte %00000111
; byte %00000010
; byte %00000010
; byte %00000110
; byte %00000010
 byte %00011111
 byte %00000100
 byte %00000100
 byte %00000100
 byte %00001100
 byte %00000000
 byte %00000000
 byte %00000000
dec2
; byte %00000111
; byte %00000100
; byte %00000010
; byte %00000001
; byte %00000110
 byte %00011111
 byte %00001000
 byte %00000100
 byte %00000010
 byte %00011100
 byte %00000000
 byte %00000000
 byte %00000000
dec3
; byte %00000110
; byte %00000001
; byte %00000110
; byte %00000001
; byte %00000110
 byte %00011110
 byte %00000001
 byte %00000110
 byte %00000010
 byte %00011100
 byte %00000000
 byte %00000000
 byte %00000000
dec4
; byte %00000001
; byte %00000001
; byte %00000111
; byte %00000101
; byte %00000001
 byte %00000100
 byte %00000100
 byte %00111110
 byte %00100100
 byte %00010100
 byte %00000000
 byte %00000000
 byte %00000000
dec5
; byte %00000110
; byte %00000001
; byte %00000111
; byte %00000100
; byte %00000111
 byte %00011110
 byte %00000001
 byte %00000110
 byte %00001000
 byte %00001111
 byte %00000000
 byte %00000000
 byte %00000000
dec6
 byte %00000111
 byte %00000101
 byte %00000111
 byte %00000100
 byte %00000011
 byte %00000000
 byte %00000000
 byte %00000000
dec7
 byte %00000010
 byte %00000010
 byte %00000001
 byte %00000001
 byte %00000111
 byte %00000000
 byte %00000000
 byte %00000000
dec8
 byte %00000111
 byte %00000101
 byte %00000010
 byte %00000101
 byte %00000111
 byte %00000000
 byte %00000000
 byte %00000000
dec9
 byte %00000110
 byte %00000001
 byte %00000111
 byte %00000101
 byte %00000111
 byte %00000000
 byte %00000000
 byte %00000000

 org $FFFC
 word $F000
 word $F000


Attachment: score.bin
Description: Binary data

Current Thread