The resetting of STIMER (53769) does work w/o any delays but trying to set the phase for the 15Khz timer using resetting of SKCTL was problematic as not all phase shift cycles (0..113) seem to work.
I also did a small test, but, isn't this caused by the memory refresh cycles?
Can you post some source?
I'm rather sure the timer itself can be synced to any desired position, at least when the INIT procedure doesn't coincide with a memory refresh or DMA cycle.
I don't have source with me on this disk I'm traveling with, I'll post the source code when I get home but I am getting a case where 3 consecutive cycles where I set INIT produce the same color patterns meaning the phase didn't move at all. (This is on Atari 800).
Interestingly, when looking at this disk I have with me, I found this source code for stabilized VBIs. You have to write your code in such a way that it's aligned on certain cycle boundaries and then you don't need to waste time with WSYNC:
;*** ATVBI.ASM: Makes VBI perfectly stable on Atari 800XL by Krishna Software Inc.
;*** This also shows how to inhibit VBI by causing IRQ to occur on same cycle as VBI...
TIMERFREQLSB = 53760
TIMERFREQMSB = 53762
WSYNC = 54282
VCOUNT = 54283
DOSVEC = 10
CASINI = 2
WARMSTART = 58484
VMIRQ = 534 ;hardware irq ptr
VBI = 546 ;Vertical Blanking Intr (NMI)
ORG = 600h
DB 0,3 ;# of sectors to load 1..255
StartAdr: Lda #MyReset,L
MyReset: Lda #2
Lda #0 ;no VBIs nor DLIs for maximum performance
Sta 53774 ;disable all IRQs
Sta 54272 ;turn off screen
Sta 54018 ;set direction ctrl for 54016
Lda #255 ;set all pins for output
Sta 54018 ;set data register at 54016
Lda #254 ;output zero on bit 0 (Pin 1)
Lda #TimerTwoIRQ,L ;general IRQ routine but we use only for timer #2
;Lda #80 ;40 for join channels 3,4; +80 for channels 1+2 @1.79Mhz
Lda #1+40 ;0 for 63Khz timers using 8-bit divisors (1 for 15.7Khz)
;+16 for 16-bit divisor on ch.1+2
Lda #165 ;lsb 172-7 for 60Hz (86-7 for 120Hz) [5,1 for 262 scanlines @15.7Khz]
Sta 53764 ;timer #2 freq = 1789790/[A+7] or 15980/[A+1]
Lda #116 ;msb for rate divisor A (58 for 120Hz, 116 for 60Hz)
Lda #0 ;disable IRQs for now
Sta 53774 ;enable/disable IRQs
FindEOS: Cmp VCOUNT
Lda #1 ;was 123
FindVBITrigger: Cmp VCOUNT
Sta 54286 ;enable VBI
;Jmp Do3Cycle ;inhibits VBI at cycle 7,8,9 after WSYNC/STIMER (on XL)
;Sta 53769 ;start timer counter
IdleLoop: ;put your code here
NextLbl: Jmp IdleLoop
;*** There's a 2 cycle difference between old OS like on Atari 800 and 800XL OS. There's no CLD instruction
;*** on older OSes before vectoring through .
ChgColor: Lda #15
Sta 53274 ;change register (like color for example)
;Sta 53274 ;change register (like color for example)
MyVBI: ;following is experiment with vbi cycle exactness (OS uses 31 cycles before our routine
;gets control. Our exit procedure is 22 cycles and vectoring uses some. This
;VBI is 14+4*(256*9-1) cycles = 9226 + 2358 refresh cycles + 60 cycle overhead.
;29868-11644 = 18224 cycles left for background (align to 67*17*16).
Sta 54016 ;output "1" in pin 1 on Left Joystick for VBI started
NxtX: Stx 53274
NxtX2: Stx 53274
NxtX3: Stx 53274
NxtX4: Stx 53274
Lda #254 ;output "0" on pin 1 for end of VBI (for now one scanline time)
Pla ;reverse stack from OS VBI entry (4 cycles)
Tay ;$A8 ;2 cycles
Pla ;$68 ;4 cycles
Tax ;$AA ;2 cycles
Pla ;4 cycles
Rti ;6 cycles
;LastOffset: DW 2e0h,2e1h,ORG