Background change at Raster Location

Basic and Machine Language

Moderator: Moderators

User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Background change at Raster Location

Post by chysn »

Consider the following simple program:

Code: Select all

A000 LDA #$3B		; Cyan and cyan
A002 LDX #$20		; Raster position for the cutoff
A004 CPX $9004	
A007 BCS $A00B
A009 LDA #F8		; After the cutoff, use light black and yellow
A00B STA $900F	; Set the screen color
A00E JMP $A000
I'm making a game, and I want the screen to be a different color on top than it is in the play field. The above mostly works, but I fear it's a bit naive to the extent that there's a bit of a flicker at the switch-over point. Is there a way to stabilize that border? I messed around with the raster bit 0 in $9003, and I didn't find a solution looking at that.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Background change at Raster Location

Post by Mike »

For this application ('merely' raster exact, but not necessarily cycle exact) there should be enough time in the HSync period to hide the colour change in the left/right border.

With NTSC, for some difficult to explain reasons, the change of the raster register happens in the middle of a raster line. With a few NOPs after the wait loop, you can 'nudge' the change into the border.

Even with a tight waiting loop, the position cannot be stabilized better than to 7 different CPU cycles. If you need an exact position, you'll need to employ a 'stable raster' IRQ. For an example of this technique, see here: "VIC 20 in Black and White mode".

Note these routines definitely need you to take differences between NTSC and PAL into account.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Background change at Raster Location

Post by chysn »

Okay, thanks. I just looked over Marko Makela's stable raster interrupt code. It'll take me a bit more time to understand it, but it seems like it's something that might be too much overhead for a game that I want to run on an unexpanded VIC, and for a single effect that won't be essential.

I might finish the game and see if I can get the effect working afterwards. I'll decide then whether the jitter is worth the trouble. Since it's background color, maybe I can even hide the jittery line under the play field, and then you'd only see it in the border....
Note these routines definitely need you to take differences between NTSC and PAL into account.
So I'd be looking for a different raster value? If #$20 is perfect for NTSC, I might need a different value for PAL?

I'm assuming that I can detect whether it's a PAL or NTSC machine by watching $9004 to see how high it gets before going back to 0?
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Background change at Raster Location

Post by Mike »

chysn wrote:Okay, thanks. I just looked over Marko Makela's stable raster interrupt code.
Marko's code is overly complicated, and I found a technically better method for myself.

He uses two VIA timers, where one is sufficient. Furthermore, he does the positioning during timer init with a linear search that uses somewhat convoluted code. In my code, I use a binary search, which syncs in faster. BTW, the top-left display window in Realms of Quest 5 also uses my stable raster routine.

But as I already wrote, I don't think you need cycle-exact code for your game. Carefully 'timing out' the position with NOP to move the register change into the left/right border should be sufficient for the job. Indeed for PAL and NTSC the value to look for in $9004 will be different.
I'm assuming that I can detect whether it's a PAL or NTSC machine by watching $9004 to see how high it gets before going back to 0?
It's much easier to check the table of the initial VIC register values beginning at $EDE4. The init value of $9000 (XPOS) at $EDE4 is 12 for PAL and 5 for NTSC.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Background change at Raster Location

Post by chysn »

Man, the rabbit hole I've gone down is blowing my mind.

I always thought I was stuck with interrupts happening 60 times per second. I had no idea that I could check which interrupt I want to handle. I never considered that I didn't really need to jump back to $EABF if it's not doing stuff I don't care about.

There's this whole section of the Programmer's Reference Guide that I never even looked at.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Background change at Raster Location

Post by Mike »

chysn wrote:There's this whole section of the Programmer's Reference Guide that I never even looked at.
You mean, pages 218 to 226? ... :mrgreen:
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Background change at Raster Location

Post by chysn »

Mike wrote: Thu Apr 16, 2020 10:17 am
chysn wrote:There's this whole section of the Programmer's Reference Guide that I never even looked at.
You mean, pages 218 to 226? ... :mrgreen:
Exactly. The pages that, once you try to open to them, the book literally starts to fall apart.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
tokra
Vic 20 Scientist
Posts: 1123
Joined: Tue Apr 27, 2010 5:32 pm
Location: Scheessel, Germany

Re: Background change at Raster Location

Post by tokra »

To be perfectly honest: I never understood (nor tried to understand) the VIA-registers myself. I used Marko's stable-raster-routine as a black-box and just recently have adapted Mike's better routine for a yet-to-come program. Does anyone know of a book/online-reference that explains these in more detail than just the pure reference?
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Background change at Raster Location

Post by srowe »

tokra wrote: Thu Apr 16, 2020 11:19 pm Does anyone know of a book/online-reference that explains these in more detail than just the pure reference?
There's quite a long section in "6502 Assembly Language Programming" by Lance Leventhal that I found useful when I was re-writing the RS-232 code.
User avatar
tokra
Vic 20 Scientist
Posts: 1123
Joined: Tue Apr 27, 2010 5:32 pm
Location: Scheessel, Germany

Re: Background change at Raster Location

Post by tokra »

srowe wrote: Fri Apr 17, 2020 12:40 am
tokra wrote: Thu Apr 16, 2020 11:19 pm Does anyone know of a book/online-reference that explains these in more detail than just the pure reference?
There's quite a long section in "6502 Assembly Language Programming" by Lance Leventhal that I found useful when I was re-writing the RS-232 code.
Found it. Thanks, this looks helpful :)
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Background change at Raster Location

Post by chysn »

Okay, here's my first crack at a timer-based interrupt designed to split screen background colors:

Code: Select all

A000 SEI
A001 LDA #$18
A003 STA $0314
A006 LDA #$A0
A008 STA $0315
A00B STA $9128 ; Start the timer latch
A00E STA $9129 ; Clear the interrupt bit, all the other stuff writing to this does
A011 LDA #$F0
A013 STA $912E ; Enable the timer 2 interrupt
A016 CLI
A017 RTS
A018 LDA $912D ; Check the source of the interrupt
A01B AND #$20
A01D BNE $A022 ; If the timer 2 interrupt is in, do the timer 2 ISR
A01F JMP $EABF ; otherwise, just go to the system ISR
A022 LDA #$08 ; Make the screen black on black
A024 LDX #$28 ; The raster switch-over point
A026 CPX $9004
A029 BCC $A02D
A02B LDA #$3B ; If the raster is lower in number (physically, higher), change to cyan on cyan
A02D STA $900F
A030 LDA #$40
A032 STA $9128 ; Re-initialize the timer
A035 LDA #$00
A037 STA $9129
A03A JMP $EB18 ; Pull the registers, RTI
The stability of the switch depends on how I set the timer latch bytes. I have to find the sweet spot between greater stability and the system continuing to work properly, and that seems to be more or less $0040, although it still drifts around quite a bit, especially when things are happening.

On an unrelated note, I've been trying to figure out the difference between

Code: Select all

LDA $912D
AND #$20
and my original approach which was

Code: Select all

LDA #$20
AND $912D
One works, and one doesn't, I have absolutely no idea why. It's kind of freaking me out. The zero flag never gets set with the second way, so the cursor never blinks. Same result when I use BIT instead of AND. For now, I'm chalking it up to some quirk with the VIA.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Background change at Raster Location

Post by Mike »

Both variants should give the same results, i.e. Akku contents and flags. The 6502 does a single read from $912D and it should not matter, whether it is from AND or LDA.

Are you testing on real hardware or in emulation? If in emulation, what version/build of VICE do you use? Some builds of VICE have difficult to track regression bugs, especially in the VIA emulation. :(

That being said, using timer 2 to trigger another interrupt just a few cycles after the first interrupt is a rather unusual method. The minimum period is mostly limited by the interrupt response time and first level interrupt handler in the KERNAL. You'd normally simply use a delay loop or a bunch of NOPs for this. But it's O.K. of course when you need two interrupts per frame because you don't want to waste 30 or so rasters in a delay loop (and don't do any raster bars, just a single different background/border colour).

I'd then however recommend you program a period in timer 1 that aligns the timer interrupt to a given raster position. Normally timer 1 runs at roughly 60 Hz (irrespective of PAL/NTSC!) and on NTSC, it's slightly different from the frame rate, so drifts, and on PAL it's effectively uncorrelated. For NTSC, you'd put 261x65-2 into timer 1, and for PAL, 312x71-2.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Background change at Raster Location

Post by chysn »

Mike wrote: Sun Apr 19, 2020 1:09 pmBoth variants should give the same results,
I know, right?! That's what's weird about it. This is a real NTSC CR VIC-20, which had a bad 6522 when I got it. Both of my current 6522s are scavenged from an early-model VIC-20. Aside from this weirdness, there's no indication that there's anything wrong. Maybe I should pick up a pair of 6522s to have around.

Maybe I'll test on VICE, although I've never really gotten the hang of it.
I'd then however recommend you program a period in timer 1 that aligns the timer interrupt to a given raster position. Normally timer 1 runs at roughly 60 Hz (irrespective of PAL/NTSC!) and on NTSC, is slightly different from the frame rate, so drifts, and on PAL it's effectively uncorrelated. For NTSC, you'd put 261x65-2 into timer 1, and for PAL, 312x71-2.
OK, I'll give that a shot. My reasoning here was that timer 1 was already occupied with the jiffy-counter, cursor-blinking ISR. It sounds like you're saying that the technique involves changing the timing of that so that the raster is in the same place during every interrupt. That provides one time reference, but it seems like I need two time reference points, because the color changes twice per frame.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Background change at Raster Location

Post by Mike »

chysn wrote:it seems like I need two time reference points, because the color changes twice per frame.
One reference point is sufficient, which is done by timer 1, and which also does the first colour change in the frame.

Timer 2 is one-shot only, i.e. you need to restart timer 2 anyhow each time from within the timer 1 service routine and do the second colour change when timer 2 triggers.

...

And yes, reprogramming the timer 1 interval will make the jiffy clock going wrong (not that it was any accurate to begin with). You should attach the standard interrupt call to $EABF with only one of the timer triggers (which you already did), note that the key scan can require up to ~40 rasters, so you should attach it there where there's more raster time available.
vicassembly
Vic 20 Devotee
Posts: 253
Joined: Fri Mar 19, 2010 1:40 pm

Re: Background change at Raster Location

Post by vicassembly »

I need help. :D

1. I am trying to follow chysn's code ideas and I think I have learned a bit about it.
2. I found Marko Makela's writeup at https://codebase64.org/doku.php?id=base ... export_pdf It was too complex for me to follow very well. A lot was due to my using cc65 and not understanding some of his code.
3. I looked for a printout of Mike's stable routine and could not find it. Mike: Could you help me with a text version of it or point me to the right place?


In short, I am attempting to have 3 sections of the screen. Up through raster switch 63 is to be blue border/blue screen. From 64-67 it is to be green border/blue screen. After 68 it is to be black border/black screen.

The first blue/blue section seems pretty stable. The green/blue area completely flickers and I can see the lines painting. The black section at the end seems pretty stable. It's the flickering of wherever the colors change.

Could you kind souls look a the code I have and let me know if you see anything I am glaringly missing? I tried to implement Chysn's code the best I could.

First: The interrupt setup.

Code: Select all

; ------------------------------------------------------------------------------------------------
; Set interupt IRQ vector to the BACKROUND routine.
; ------------------------------------------------------------------------------------------------
SETBACKGROUNDIRQ:
        LDA CINVL
        STA SAVEIRQ1
        LDA CINVH
        STA SAVEIRQ2
        SEI
        LDX #<BACKGROUND
        LDY #>BACKGROUND
        STX CINVL	; enable my IRQ vector jump
        STY CINVH
        LDY #$A0
        STY VIA2T2CL  ; start the timer latch
        STY VIA2T2CH  ; clear the interrupt bit
        LDA #$F0
        STA VIA2IER
        CLI
        RTS
next the interrupt code.

Code: Select all

; ------------------------------------------------------------------------------------------------
; interesting raster stuff
; ------------------------------------------------------------------------------------------------
BACKGROUND:
        LDA VIA2IFR
        AND #$20      ; 0010 0000   Bit 5 of timer two interrupt is 0 when timer 2 in and 1 when
                            ;             timer 2 expires.
        BNE @CONT1    ;    When timer 2 is IN then do something
       JMP $EABF        ;             otherwise jump to hardware IRQ
@CONT1: LDA SCREENCOLOR1
        LDX VIC+$04      ; check raster at 36868
        CPX #$64         ; raster switch over point 1
        BCC @HERE
        LDA SCREENCOLOR2
        CPX #$68         ; raster switch over point 2
        BCC @HERE
        LDA SCREENCOLOR3
@HERE:  STA VIC+$0F   ; 36879
        LDA #$40      ; re-initialize the timer
        STA VIA2T2CL
        LDA #$00
        STA VIA2T2CH
        JMP $EB18     ; pull registers and RTI
The symbols are defined here.

Code: Select all

; pertinent VIC20 symbols
TIMEH  		= $A0
TIMEM	  	= $A1
TIMEL 		= $A2		  ; jiffy-clock low byte value
COLORPAGE	= $F4		  ; high order byte of screen color page
SCRNPAGE	= $0288		; screen memory page (unexpanded = 1E)
CINVL     = $0314   ; Vector to Interrupt routine
CINVH     = $0315
VIC			  = $9000		; start of video interface chip registers

CHARDATA  = $1C00		; character definitions
SCREEN    = $1E00   ; Top left of Screen (unexpanded)
COLOR     = $9600   ; Color for top left of screen (unexpanded)

; VIA2 addresses
VIA2T2CL  = $9128   ; Timer 2 low order LSB counter and LSB latch
VIA2T2CH  = $9129   ; Timer 2 high order MSB and MSB latch
VIA2IFR   = $912D   ; Interupt flag register
VIA2IER   = $912E   ; Interrupt enable register
(mod: code put in code tags)
Post Reply