This works fine, and very well..
On top of that, I also want to blank the top of the display to hide the offscreen region so it scroll on smoothly without having to have the top of the display off the screen..
This doesn't work so smoothly

I found that setting Width to 0 hides the display, but when combined with the other effects I'm unable to move the screen down by more than 8 pixels in 8x8 mode, 16 in 8x16 mode.. Removing the code that sets width to 0 indicates the logic is all cool, and the screen is moving the desired amount, but with it in it doesn't..
Logic follows like this:
Raster Line 0: Set HPOS to 0
On the first (off screen line) Set HPOS to 12
On the first displayed line: Set WIDTH to 22
That works fine, and I see the screen moving as it should, but obviously the top is visibly moving up and down..
Now if on Raster line 0 I set WIDTH to 0 in addition to HPOS something very weird happens and I appear to lose one of the zero width lines..
I also noticed that I'm getting one link of junk at the bottom of the screen, which I expect using the HPOS method, but sometimes it's also going to 2 lines depending upon the Y value I use..
I suspect I'm just missing something in how the VIC uses the Width value when it's zero.. Or maybe the point in the raster line where I'm changing HPOS or WIDTH..
Code: Select all
Raster1 = 25 ; First distance..
Raster2 = 8
Raster3 = 16
Raster4 = 42
Raster0 = 52+169 ; Last distance..
!to "main.prg", cbm
!cpu 6510
!ct pet
; VIC20 BASIC stub
; * = $401 ;3k
* = $1001 ;Unexpanded
; * = $1201 ;8k+
BASICstub !word next_line ; Calculate pointer to next BASIC line
!word 2012 ; BASIC Line# (change this to any # you want)
!byte $9e ; BASIC token for SYS
!byte <(Initialise / 1000 % 10) + $30
!byte <(Initialise / 100 % 10) + $30
!byte <(Initialise / 10 % 10) + $30
!byte <(Initialise / 1 % 10) + $30
!byte 0 ; End of BASIC line
next_line !byte 0,0 ; The next BASIC line would start here
Main:
cli
lda #0
MainLoop:
jmp MainLoop
SCREENY !byte 0
YSCROLL !byte 0
IRQ:
dec $900F
lda $9124
lda #0
sta CurrentRaster
lda #<NMI0
sta $0318
lda #>NMI0
sta $0319
lda SCREENY
clc
adc #1
sta SCREENY
and #15
sta YSCROLL
lsr
clc
adc #17
sta $9001
ldy YSCROLL
lda LineTime_lo,y
clc
adc #<((71*Raster2)-2)
sta RasterTimes_lo+0
lda LineTime_hi,y
adc #>((71*Raster2)-2)
sta RasterTimes_hi+0
lda #<((71*Raster3)-2)
sec
sbc LineTime_lo,y
sta RasterTimes_lo+1
lda #>((71*Raster3)-2)
sbc LineTime_hi,y
sta RasterTimes_hi+1
lda #50
sta $9003
inc $900f
jmp $eb18
!align 255,0
; Line #0 of the frame..
NMI0:
inc $900F
sta .save_a
lda #$0 ; Set HPOS and WIDTH to 0..
sta $9000
sta $9002
lda #<NMI1
jmp NMI_Exit
; This NMI is just a dummy since we need 2 timer latches to occur, and whilst it could work without
; it's easier since the scroll will work as long as the new scroll value is set by line #0 of the new frame..
NMI1:
inc $900F
sta .save_a
lda #<NMI2
jmp NMI_Exit
; Variable by +15 lines to control HPOS setting to move screen by one line..
NMI2:
inc $900F
sta .save_a
lda #$0C ; Restore the correct HPOS on the exact scanline to undelay scanline..
sta $9000
lda #<NMI3
jmp NMI_Exit
; Fixed at the display start to reset screen from 0 width back to normal width, unblanking it essentially..
NMI3:
inc $900F
sta .save_a
lda #$80+22 ; Restore correct width now..
sta $9002
lda #<NMI4
jmp NMI_Exit
NMI4:
inc $900F
sta .save_a
lda #<NMI0
jmp NMI_Exit
NMI_Exit:
sta $0318
stx .save_x
CurrentRaster = * + 1
ldx #0
lda RasterTimes_lo,x
sta $9116
lda RasterTimes_hi,x
sta $9117
inx
stx CurrentRaster
.save_x = * + 1
ldx #0
.save_a = * + 1
lda #0
dec $900F
rti
NMI_JUMP !word NMI0
RasterTimes_lo
!byte <((71*Raster2)-2)
!byte <((71*Raster3)-2)
!byte <((71*Raster4)-2)
!byte <((71*Raster0)-2)
!byte <((71*Raster1)-2)
RasterTimes_hi
!byte >((71*Raster2)-2)
!byte >((71*Raster3)-2)
!byte >((71*Raster4)-2)
!byte >((71*Raster0)-2)
!byte >((71*Raster1)-2)
LineTime_lo !for .i, 0, 16 { !byte <(.i*71) }
LineTime_hi !for .i, 0, 16 { !byte >(.i*71) }
Initialise:
sei
; Disable all interrupt sources, and stop the timers..
lda #$7F
sta $911E
sta $912D
sta $912E
; Enable Timer #1 on both VIAs..
lda #$40
sta $911B
lda #$40
sta $912B
; Set our NMI & IRQ vectors up..
lda #<IRQ
sta $0314
lda #>IRQ
sta $0315
lda #<NMI0
sta $0318
lda #>NMI0
sta $0319
; Load the low bytes of Timer #1 on both VIAs..
lda #<((312*71)-2)
sta $9116
sta $9126
ldx #>((312*71)-2)
; Sync the IRQ to raster line 260..
lda #134
- cmp $9004
bne -
stx $9125
; Sync the NMI up to line 0..
lda #0
- cmp $9004
bne -
stx $9115
; Enable IRQs and NMIs for Timer #1 on both VIAs..
lda #$c0
sta $911E
sta $912E
; Set the next timer value for the NMI into the latches.. So, on raster line 0..
lda #<((Raster1*71)-2)
sta $9116
lda #>((Raster1*71)-2)
sta $9117
jmp Main