Draw on screen border in Commodore 64

Viewed 8524

I have this curiosity for 25 years and I would love to understand the trick.

In the Commodore 64 the border was not addressable by the 6569 VIC. All you could do was to draw pixels in the central area, the one where the cursor moved. The border was always uniform, although you could change its color with poke 53280,color if i remember correctly.

Nevertheless I clearly remember games intros where the border was featured with graphics, like it was fully addressable. I tried to understand how it worked but never got to the point. legends say it was a clever use of sprites, which could, under some circumstances, be drawn on the border, but I don't know if it's an urban legend.

edit: just read this from one of the provided links

Sprites were multiplexed across vertical raster lines (over 8 sprites, sometimes up to 120 sprites). Until the Group Crest released Krestage 3 in May 2007 there was the common perception that no more than 8 sprites could appear at one raster line, but assigning new Y coordinates made it reappear further down the screen.

This is evil.... you beat the raster and reposition the sprite before it gets there...

9 Answers

The Microsoft flight simulator drew on the border. For one, we can achieve border drawing effects by changing the border color at the right time. LOGO for example had a split screen mode for the Turtle graphics, where the screen was switched between HiRes graphics above and a few lines of text below. The frame was also differently colored. So it is easy to do a horizon effect, green pastures below and blue sky above (as in the Flight Simulator) which effect extends to the frame.

When you run the wild frame flicker program, like

   C000 LDX #00
        STX D020
        INX
        STX D020
        DEX
        BEQ C002

then you get the color to change at every 10-20 pixels or so. That's the fastest change you can get, I think. So you can draw a horizontal line on the border. fastest change of border color

And you can time this by using the same vertical line register in the VIC at $D012 and the bit 7 of $D011, You can read the current scan line from that register. But if you write to it, and you enable the low bit in the register $D01A then the VIC will signal and IRQ when the scan hits that line. So that's how the split screen effect is accomplished.

Here is an example. First I set up my interrupt routine:

   C000 SEI        ; disable interrupt
        LDA #1F    ; set interrupt routine to C01F
        STA 0314   ; set low byte
        LDA #C0    ; high byte
        STA 0315   ; set
        LDA #C0    ; raster position for horizon
        STA D012   ; set to raster position interrupt
        LDA D011   ; and for the high bit of the raster position
        AND #7F    ; clear the high bit
        STA D011   ; and set the cleared high bit
        LDA #F1    ; enable the raster interrupt
        STA D01A   ; in the appropriate register
        CLI        ; allow interrupt
        RTS        ; return from subroutine

And here is my actual interrupt routine now:

   C01F LDA D019   ; load VIC interrupt register
        STA D019   ; and clear it
        BMI C02E   ; if highest bit is set, go to our routine
        LDA DC0D   ; else disable CIA interrupt
        CLI        ; enable interrupt
        JMP EA31   ; continue with normal system interrupt routine

   C02E LDA D012   ; load current vertical scan line
        CMP #01    ; is it just about the first line?
        BCS C042   ; if not jump to bottom part
        LDA #03    ; cyan
        STA D020   ; set border color (sky)
        LDA #C0    ; horizon level 
        STA D012   ; set vertical scan interrupt to occur at horizon
        JMP EA81   ; continue with normal interrupt minus cursor blink

   C042 LDA #00    ; black to draw a piece of horizontal line on the horizon
        STA D020   ; set border color
        LDX #08    ; a short busy loop
   C049 DEX
        BNE C049
        LDA #01    ; white to draw on the right side horizon
        STA D020   ; set border color
        LDX #02    ; very short busy loop
   C053 DEX
        BNE C053
        LDA #05    ; finally green as the grass
        STA D020   ; set border color
        LDA #00    ; next scan line interrupt at top of screen
        STA DO12   ; set scan line interrupt
        JMP EA81   ; continue normal interrupt sans cursor blink 

With the following glorious result: split screen with two line segments drawn on the horizon

Graphics in border: Either sprites OR using the $3FFF effect (which is actually NOT sprites at all). To go into in detail needs much more space and time than I have available here.

Related